DuendeSoftware / IdentityServer

The most flexible and standards-compliant OpenID Connect and OAuth 2.x framework for ASP.NET Core
https://duendesoftware.com/products/identityserver
Other
1.45k stars 337 forks source link

improve youngest key search #1584

Open testfirstcoder opened 1 month ago

testfirstcoder commented 1 month ago
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)