Atomized XName and XNamespace Objects

Introduction

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOCXName and XNamespace objects are atomized. This yields performance benefits for queries: comparing two atomized names for equality means that the underlying intermediate language (IL) only needs to determine if the two references point to the same object. The underlying system does not need to do any string comparisons, which would be time consuming.

You need not take any special action to reap these benefits; however it is useful to understand the dynamic.

Atomization Semantics

Atomization means that if two XName objects have the same local name, and they are in the same namespace, then they will share the same instance. In the same way, if two XNamespace objects have the same namespace URI, then they will share the same instance.

This is similar in idea to how strings are interned. The common language runtime conserves string storage by maintaining a table, called the intern pool, which contains a single reference to each unique literal string declared in your program. Consequently, an instance of a literal string with a particular value only exists once in the system. Further, you can use the System.String.Intern(System.String) method to programmatically intern a string.

To enable atomization of XName objects, the constructor is not public, so you are not able to directly instantiate an XName object. The XName class implements an implicit operator to convert from a string to an XName; this is how you get an XName instance, rather than instantiating using a constructor. The XName also implements the equality and inequality operator. The implementation of these operators simply determine if the two objects being compared are in fact references to the same instance. There is a little more to it than this, but this is the gist of the implementation.

XNamespace objects are atomized in the same fashion.

Example

The following code creates some XElement objects and demonstrates that identical names share the same instance.

[c#]

XElement r1 = new XElement("Root", "data1");

XElement r2 = XElement.Parse("<Root>data2</Root>");

 

if ((object)r1.Name == (object)r2.Name)

    Console.WriteLine("r1 and r2 have names that refer to the same instance.");

else

    Console.WriteLine("Different");

 

XName n = "Root";

 

if ((object)n == (object)r1.Name)

    Console.WriteLine("The name of r1 and the name in 'n' refer to the same instance.");

else

    Console.WriteLine("Different");

 

This example produces the following output:

 

r1 and r2 have names that refer to the same instance.

The name of r1 and the name in 'n' refer to the same instance.

 

What this means in practical terms is that when you use one of the axis methods that take an XName as a parameter, the axis method needs to only determine that the names point to the same instance to select the desired elements. In other words, it requires only a reference comparison, not something more expensive in terms of performance, such as a string comparison. In the following example, these semantics are used within the Descendants method call.

[c#]

XElement root = new XElement("Root",

    new XElement("C1", 1),

    new XElement("Z1",

        new XElement("C1", 2),

        new XElement("C1", 1)

    )

);

 

var query = from e in root.Descendants("C1")

            where (int)e == 1

            select e;

 

foreach (var z in query)

    Console.WriteLine(z);

 

This example produces the following output:

<C1>1</C1>

<C1>1</C1>