Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
                    }
like image 853
Jeroen Avatar asked Aug 09 '10 16:08

Jeroen


People also ask

Is LINQ foreach faster?

In general, for identical code, linq will be slower, because of the overhead of delegate invocation. You use an array to store the data. You use a for loop to access each element (as opposed to foreach or linq).

Is LINQ slow unity?

LINQ. requires more computation time and creates more garbage because of the boxing that goes on behind the scenes. For context, dotnetperls did a loop vs LINQ test over some data and found that LINQ was almost 10X slower.

Is for faster than foreach C#?

Foreach performance is approximately 6 times slower than FOR / FOREACH performance. The FOR loop without length caching works 3 times slower on lists, comparing to arrays. The FOR loop with length caching works 2 times slower on lists, comparing to arrays.

Is LINQ faster than SQL?

Even if you don't write SQL inside the program, Linq makes it possible to write code which is more like functional programming. Sql is faster than Linq. Its simple: if I m executing a sql query directly its a one way process whereas if I m using linq, first its been converted to sql query and then its executed.


2 Answers

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?

like image 153
Jon Skeet Avatar answered Sep 19 '22 15:09

Jon Skeet


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.

like image 29
Billy ONeal Avatar answered Sep 18 '22 15:09

Billy ONeal