Some performance issues and caveats of LINQ
20% of the code executes 80% of the time
As you may already know, Linq to collections generally performs worse, than the hard-coded approach. That happens because we deal with the iterator classes and lazy evaluation.
Most of the time this is not a problem, since the impact on the overall performance is negligible. And the code itself gets much cleaner and easier to read.
However, in the high-stress scenarios (i.e.: in heavy math calculations) improper Linq usage could become a problem. Let's write a couple of micro-benchmarks and compare the performance of hand-written loops with the Linq.
In simple selection and sum Linq works just x1.5 times slower:
// Loop - 01.73 s
for (int j = 0; j < array.Length; j++)
{
var v = array[j].Value;
if (v > Math.PI)
{
sum1 += v;
}
}
// LINQ - 02.54 s
sum2 += array.Where(o => o.Value > Math.PI).Sum(o => o.Value);
But the difference could get bigger (x2.6), if we forget, that Linq does the lazy evaluation:
// Loop - 01.77 s
for (int j = 0; j < array.Length; j++)
{
var v = array[j].Value;
if (v > Math.PI)
{
sum1 += v;
total1 += 1;
}
}
// Linq - 04.60 s
var doubles = array.Where(o => o.Value > Math.PI);
total2 += doubles.Count();
sum2 += doubles.Sum(o => o.Value);
One could be tempted to use .ToArray() to force the evaluation once, but this has its own cost and will degrade the performance even more (x3.1):
// Linq - 05.43 s
for (int i = 0; i < 100000; i++)
{
var doubles = array
.Select(o => o.Value)
.Where(d => d > Math.PI)
.ToArray();
total2 += doubles.Count();
sum2 += doubles.Sum();
}
Resume: Linq is sharp. There is a lot of stuff going inside these simple looking extension methods for collections. Just be careful with them, while writing performance-critical code, and you should be fine.
Appendix: these micro-snippets have been executed against array generated like this:
var r = new Random(1);
var array = Enumerable.Range(1, 1000)
.Select(i => new
{
ID = i,
Name = "Item_" + i,
Category = "Category_" + (i%10),
Value = r.NextDouble()*10
})
.ToArray();
Note: we use randSeed parameter to create repeatable experiment results.
Every statement was compiled in "Release" mode and executed 100000 times. Total execution time was measured with the Stopwatch class.
Thursday, September 25, 2008 at 2:18
Reader Comments (2)
The popular Alma MM Roses Handbag fromtag heuer formula|
Louis Vuitton has been given a twist of Stephen Sprouses signature style.
really hard for me
ffxiv gil