Skip to content

Instantly share code, notes, and snippets.

@SelvinPL
Last active July 4, 2023 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SelvinPL/84d739a65059dfafb80b0ef1b71a767f to your computer and use it in GitHub Desktop.
Save SelvinPL/84d739a65059dfafb80b0ef1b71a767f to your computer and use it in GitHub Desktop.
SO76611515
void Main()
{
var summary = BenchmarkRunner.Run<Test>();
}
public class Test
{
[Benchmark]
public void Max()
{
TestData.GroupBy(a => new { a.B, a.C })
.Select(g => new A { B = g.Key.B, C = g.Key.C, D = g.Max(a => a.D), E = g.Max(a => a.E) }).ToList();
}
[Benchmark]
public void Any()
{
TestData.GroupBy(a => new { a.B, a.C })
.Select(g => new A { B = g.Key.B, C = g.Key.C, D = g.Any(a => a.D), E = g.Any(a => a.E) }).ToList();
}
[Benchmark]
public void Aggregate()
{
TestData.GroupBy(a => new { a.B, a.C })
.Select(g => g.Aggregate(new A { B = g.Key.B, C = g.Key.C }, (ar, a) => { ar.D |= a.D; ar.E |= a.E; return ar; })).ToList();
}
[Benchmark]
public void AggregateUntil()
{
TestData.GroupBy(a => new { a.B, a.C })
.Select(g => g.AggregateUntil(new A { B = g.Key.B, C = g.Key.C }, (ar, a) => { ar.D |= a.D; ar.E |= a.E; return (ar.D && ar.E, ar); })).ToList();
}
List<A> TestData { get; } = new List<A>
{
//first D and E are tru so Any will return immediately
new A { B = 1, C = 1, D = true, E = true },
new A { B = 1, C = 2, D = true, E = true },
new A { B = 1, C = 3, D = true, E = true },
new A { B = 1, C = 4, D = true, E = true },
new A { B = 1, C = 5, D = true, E = true },
new A { B = 1, C = 6, D = true, E = true },
new A { B = 1, C = 7, D = true, E = true },
//second
new A { B = 1, C = 1, E = true },
new A { B = 1, C = 2, E = true }
};
}
public class A
{
public int B { get; set; }
public int C { get; set; }
public bool D { get; set; }
public bool E { get; set; }
}
static class Ext
{
public static TAccumulate AggregateUntil<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, (bool, TAccumulate)> func)
{
foreach(var item in source)
{
var res = func(seed, item);
if(res.Item1)
return res.Item2; // fast lane
seed = res.Item2;
}
return seed;
}
}
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621
12th Gen Intel Core i7-12700H, 1 CPU, 20 logical and 14 physical cores
[Host] : .NET Framework 4.8 (4.8.9166.0), X86 LegacyJIT
DefaultJob : .NET Framework 4.8 (4.8.9166.0), X86 LegacyJIT
| Method | Mean | Error | StdDev |
|
--------------- |-----------:|--------:|--------:|
| Max | 1,434.2 ns | 7.55 ns | 7.06 ns |
| Any | 927.8 ns | 6.60 ns | 5.85 ns |
| Aggregate | 774.2 ns | 6.25 ns | 5.85 ns |
| AggregateUntil | 797.0 ns | 5.62 ns | 5.25 ns |
BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1848/22H2/2022Update/SunValley2)
12th Gen Intel Core i7-12700H, 1 CPU, 20 logical and 14 physical cores
.NET SDK=7.0.304
[Host] : .NET 6.0.18 (6.0.1823.26907), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev |
|--------------- |---------:|--------:|--------:|
| Max | 841.0 ns | 8.55 ns | 8.00 ns |
| Any | 780.9 ns | 3.27 ns | 3.06 ns |
| Aggregate | 652.6 ns | 4.06 ns | 3.60 ns |
| AggregateUntil | 639.1 ns | 4.86 ns | 4.54 ns |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment