views:

161

answers:

4

Hi,

I'm iterating over an anonymous type with about 1000 elements.

The question here is how is it possible that my loop takes almost 3 seconds to complete while what inside the loops happens takes less than 1 ms. With a thousand elements i figure the loop must finish within the second, not 3.

Is there a way to make it iterate faster?

// takes 1ms to complete
        var x = tt.Where(p => p.Methods.Count() > 0 && p.PerWeek != this.Project.WorkDaysCount && !p.IsManual);

// takes almost 3 seconds to complete
                    foreach (var item in x)
                    {
                        // do stuff that takes < 1 ms
                    }
+14  A: 

Linq uses delayed execution. Your linq query doesn't actually execute until someone uses the IEnumerable returned. The execution time you are seeing is the result of the query, not the foreach.

Billy ONeal
Ofcourse. I didn't realize. Thanks.
Jeroen
+7  A: 

It's deferred execution. write x.ToList(); and it will take ~ 3 seconds too.

BioBuckyBall
+14  A: 

Two immediate suggestions:

  • Don't use p.Methods.Count() > 0 - that needs to perform a full count, even though you only need to know if there are any elements. Use p.Methods.Any() instead.
  • Don't compute this.Project.WorkDaysCount on every iteration. We don't know the details of what's going on there, but it may be expensive. Precompute it, and use the constant.

Here's the improved query code:

int workDaysCount = Project.WorkDaysCount;
var x = tt.Where(p => p.Methods.Any() && 
                 p.PerWeek != workDaysCount &&
                 !p.IsManual);

As others have said, the reason the query construction itself doesn't take any significant time is that's it's not doing any real work. However, knowing that doesn't make it any faster, of course :)

Beyond that, we're going to need to know more about the context. Is this LINQ to Objects, LINQ to SQL, or something else? What's the type of tt?

Jon Skeet
This is part of quite a complex module. tt is the result of a group by and builds a sub collection .Methods based on some criteria. It's linq to objects. Based on your info i think i can optimize further. Thanks!
Jeroen
+1  A: 

Your IEnumerable (x) won't be evaluated until you materialise it

nonnb