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.
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 6 and 7 and type the answer here: