Jeroen
Jeroen

Reputation: 4023

linq foreach performance

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
                    }

Upvotes: 7

Views: 809

Answers (4)

StuartLC
StuartLC

Reputation: 107237

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

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499860

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?

Upvotes: 15

&#181;Bio
&#181;Bio

Reputation: 10748

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

Upvotes: 7

Billy ONeal
Billy ONeal

Reputation: 106530

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.

Upvotes: 14

Related Questions