More LINQ Optimizations

Not every optimization is a performance optimization. Imagine trying to get this XML:

string xml = 
    @"<people>
        <Person>
          <property value=""John"" name=""firstName""/>
          <property value=""Dow"" name=""lastName""/>
          <property value=""john@blah.com"" name=""email""/>
        </Person>
        <Person>
          <property value=""Jack"" name=""firstName""/>
          <property value=""Dow"" name=""lastName""/>
          <property value=""jack@blah.com"" name=""email""/>
        </Person>
      </people>";

Into objects of this type:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

A brute force solution would look like the following:

var xmlDoc = XDocument.Parse(xml);
var records =
    from record in xmlDoc.Descendants("Person")
    select new Person
    {
        FirstName = (from p in record.Elements("property") 
                    where p.Attribute("name").Value == "firstName"
                    select p.Attribute("value").Value).FirstOrDefault(),
        LastName = (from p in record.Elements("property") 
                    where p.Attribute("name").Value == "lastName"
                    select p.Attribute("value").Value).FirstOrDefault(),
        Email = (from p in record.Elements("property")
                 where p.Attribute("name").Value == "email"
                 select p.Attribute("value").Value).FirstOrDefault(),

    };

It works - but it’s ugly. It would be better if the code looked like this.

var records =
    from record in xmlDoc.Descendants("Person")
    select new Person
    {
        FirstName = record.Property("firstName"),
        LastName = record.Property("lastName"),
        Email = record.Property("email")
    };

Which just requires a bit of extension method magic.

public static string Property(
    this XElement element, string name)
{
    return
        (from p in element.Elements("property")
         where p.Attribute("name").Value == name
         select p.Attribute("value").Value).FirstOrDefault();
}

Is the code faster? Probably not – but until it’s certain that we have a performance problem, it’s better to optimize for readability.

Print | posted @ Thursday, February 12, 2009 2:12 AM

Comments on this entry:

Gravatar # re: More LINQ Optimizations
by Raoul at 2/12/2009 10:35 AM

Very nice. Of course I'd want to know why the XML was structured in such a weird way.

I have seen this sort of "lets implement our own schema mechanism on top of something that already has a schema mechanism" approach before and it is seldom a good idea. It is certainly not working with the grain of XML.

The fact that the LINQ/C# toolset is powerful enough to allow us to recover without too many contortions is nice though.
  
Gravatar # re: More LINQ Optimizations
by scott at 2/12/2009 2:22 PM

@Raoul:

Agreed. There are some strange XML docs floating around out there. A lot of them are in the healthcare industry :)
  
Gravatar # re: More LINQ Optimizations
by Mike at 2/12/2009 7:01 PM

I'd say these types of optimizations (for readability, testability, etc) are more important than speed optimizations, esp if there are no speed problems from the user's perspective.
  
Comments have been closed on this topic.
Scott Allen
Posts - 869
Comments - 4493
Stories - 14