Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
LinqOptimisation Benchmarks - Where Select
namespace LinqOptimisationBenchmarks
{
[Config(typeof(BenchmarkConfig))]
public class WhereSelectBenchmarks
{
private static readonly int[] items;
static WhereSelectBenchmarks()
{
items = Enumerable.Range(0, 1000).ToArray();
}
[Benchmark(Baseline = true)]
public int Iterative()
{
var counter = 0;
foreach (var item in items)
{
if (item % 10 == 0)
counter += item + 5;
}
return counter;
}
[Benchmark]
[Shaman.Runtime.NoLinqRewrite] // Yay, this works!!
public int Linq()
{
var results = items.Where(i => i % 10 == 0).Select(i => i + 5);
var counter = 0;
foreach (var result in results)
{
counter += result;
}
return counter;
}
[Benchmark]
public int RoslynLinqRewrite()
{
var results = RoslynLinqRewriteWhereSelect_ProceduralLinq1(items);
var counter = 0;
foreach (var result in results)
{
counter += result;
}
return counter;
}
System.Collections.Generic.IEnumerable<int> RoslynLinqRewriteWhereSelect_ProceduralLinq1(int[] _linqitems)
{
if (_linqitems == null)
throw new System.ArgumentNullException();
for (int _index = 0; _index < _linqitems.Length; _index++)
{
var _linqitem = _linqitems[_index];
if (_linqitem % 10 == 0)
{
var _linqitem1 = _linqitem + 5;
yield return _linqitem1;
}
}
}
// This is the correct way to cache LinqOptimiser expressions
// See https://gist.github.com/krontogiannis/362c586e709639a60e3cd0ac3fb9abc9#file-linq-bench-cs
private static readonly Func<int[], IEnumerable<int>> compiledWhereSelectQuery = Extensions.Compile<int[], IEnumerable<int>>(ps => ps.AsQueryExpr().Where(i => i % 10 == 0).Select(i => i + 5));
[Benchmark]
[Shaman.Runtime.NoLinqRewrite]
public int LinqOptimiser()
{
IEnumerable<int> results = compiledWhereSelectQuery(items);
var counter = 0;
foreach (var result in results)
{
counter += result;
}
return counter;
}
}
}

Where is the source of BenchmarkConfig?

@AndreyAkinshin BenchmarkConfig is from the BenchmarkDotNet library: https://github.com/PerfDotNet/BenchmarkDotNet

Owner

@AndreyAkinshin Oh yeah, I forgot to include that, it's pretty simple though:

class BenchmarkConfig : ManualConfig
{
    public BenchmarkConfig()
    {
        Add(JitOptimizationsValidator.FailOnError);
        Add(new MemoryDiagnoser());
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment