Tricks you can play on yourself #789Linq

Posted by: Eric Gunnersons C# Compendium, on 28 Oct 2014 | View original | Bookmarked: 0 time(s)

I was profile some code this morning, and came across some interesting behavior.

Basically, we had some low level code that looked something like this:

IEnumerable<Guid> GetSpecialQuestionIds()
{
    return
      GetAllSpecialItems()
        .Select(specialItemXml => specialItemXml .CreateFromXml(questionXml))
        .SelectMany(specialItem => specialItem.Questions.Select(question => question.UniqueIdentifier)).Distinct();
        .Distinct();
}

So, its taking special item xml, deserializing each special item, and then grabbing all the unique question ids that are referenced by the special items. Perfectly reasonable code.

Elsewhere, we did the following (the original code was spread out over 3 different classes but Ive simplified it for you):

var specialQuestionIds = GetSpecialQuestionIds();

foreach (Item item in items)
{
    var questions = item.Questions.Where(question => specialQuestionIds.Contains(question.UniqueIdentifier);
}

That also looks fine, but when I looked at the profile, I found that it was heavily dominated by the CreateFromXml() call. Well, actually, I did the profile first, and then looked at the code.

The problem is the call to Contains(). It will walk every entry in specialQuestionIds, which normally would be fine, but because its never been realized, it will deserialize all the special items for every question in every item.

The fix is pretty simple I changed GetSpecialQuestionIds() to call .ToList(), so that the deserialization only happened once, and the deserialization dropped from 65% down to 0.1% in the profile. And there was much rejoicing.

The lesson is that you should be careful whenever you return an IEnumerable<T> that isnt super-cheap, because the person who gets it may enumerate it over and over.

Category: XML | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 513 | Hits: 13

Similar Posts

  • Linking Zune media items with LinQ, Part 1 (Matt Gertz) more
  • Audio junkie – FooBar 2000 more
  • Podcast (RSS) to Playlist more
  • Silverlight and Sunday night football more
  • LINQ in Action samples in LINQPad more
  • WPF Drag and Drop Between ItemsControls more
  • WPF Image Sequencer (for animations) more
  • Creating LINQToTwitter library using LinqExtender more
  • Fluent Animations in Silverlight more
  • XM Radio Player Part II : Scraping more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD