IdentityServer
IdentityServer copied to clipboard
improve youngest key search
-
use MaxBy method instead of OrderByDescending and First methods.
record KeyContainer(DateTime Created);
[SimpleJob(RuntimeMoniker.Net80)]
[MemoryDiagnoser]
public class Benchmark
{
private IEnumerable<KeyContainer> keys =
[
new KeyContainer(DateTime.Now),
new KeyContainer(DateTime.Now.AddMinutes(1)),
new KeyContainer(DateTime.Now.AddDays(1)),
];
[Benchmark]
public void OrderByDescending_First()
{
var youngestKey = keys.OrderByDescending(x => x.Created).First();
}
[Benchmark]
public void MaxBy()
{
var youngestKey = keys.MaxBy(x => x.Created);
}
[Benchmark]
public void OrderBy_First()
{
var oldestKey = keys.OrderBy(x => x.Created).First();
}
[Benchmark]
public void MinBy()
{
var oldestKey = keys.MinBy(x => x.Created);
}
}
void Main()
{
var now = DateTime.Now;
IEnumerable<KeyContainer> keys =
[
new KeyContainer(now),
new KeyContainer(now.AddMinutes(1)),
new KeyContainer(now.AddDays(1)),
];
// youngest
Debug.Assert(keys.OrderByDescending(x => x.Created).First().Equals(keys.MaxBy(x => x.Created)));
// oldest
Debug.Assert(keys.OrderBy(x => x.Created).First().Equals(keys.MinBy(x => x.Created)));
BenchmarkRunner.Run<Benchmark>();
}
// * Summary *
BenchmarkDotNet v0.14.0, Windows 10 (10.0.19045.4780/22H2/2022Update)
Intel Core i7-10700 CPU 2.90GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 8.0.401
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job=.NET 8.0 Runtime=.NET 8.0
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|------------------------ |---------:|---------:|---------:|-------:|----------:|
| OrderByDescending_First | 76.75 ns | 1.049 ns | 0.930 ns | 0.0162 | 136 B |
| MaxBy | 22.58 ns | 0.114 ns | 0.095 ns | 0.0038 | 32 B |
| OrderBy_First | 66.32 ns | 0.490 ns | 0.458 ns | 0.0162 | 136 B |
| MinBy | 37.30 ns | 0.754 ns | 0.705 ns | 0.0038 | 32 B |
// * Hints *
Outliers
Benchmark.OrderByDescending_First: .NET 8.0 -> 1 outlier was removed (80.51 ns)
Benchmark.MaxBy: .NET 8.0 -> 2 outliers were removed (24.67 ns, 24.80 ns)
Benchmark.MinBy: .NET 8.0 -> 1 outlier was detected (37.26 ns)
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Gen0 : GC Generation 0 collects per 1000 operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 ns : 1 Nanosecond (0.000000001 sec)