Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 75 additions & 75 deletions BitFaster.Caching.Benchmarks/DisposerBench.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using BenchmarkDotNet.Attributes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Diagnostics.Runtime.Interop;

namespace BitFaster.Caching.Benchmarks
{
// Is it possible to write a class to eliminate the dispose code for types that are not IDisposable?
// https://github.com/dotnet/runtime/issues/4920
[DisassemblyDiagnoser(printSource: true)]
[MemoryDiagnoser]
public class DisposerBench
using System.Text;
using BenchmarkDotNet.Attributes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Diagnostics.Runtime.Interop;
namespace BitFaster.Caching.Benchmarks
{
// Is it possible to write a class to eliminate the dispose code for types that are not IDisposable?
// https://github.com/dotnet/runtime/issues/4920
[DisassemblyDiagnoser(printSource: true)]
[MemoryDiagnoser]
public class DisposerBench
{
[Benchmark(Baseline = true)]
public void HandWritten()
{
for (int i = 0; i < 1000; i++)
{
[Benchmark(Baseline = true)]
public void HandWritten()
{
for (int i = 0; i < 1000; i++)
{
NotDisposable notDisposable = new NotDisposable();
Disposable disposable = new Disposable();
Disposable disposable = new Disposable();
disposable.Dispose();
}
}
}

[Benchmark()]
public void NotOptimized()
[Benchmark()]
public void NotOptimized()
{
for (int i = 0; i < 1000; i++)
{
for (int i = 0; i < 1000; i++)
{
NotDisposable notDisposable = new NotDisposable();
Disposable disposable = new Disposable();

Expand All @@ -45,69 +45,69 @@ public void NotOptimized()
}
}

[Benchmark()]
public void GenericDisposerReadonlyProperty()
[Benchmark()]
public void GenericDisposerReadonlyProperty()
{
for (int i = 0; i < 1000; i++)
{
for (int i = 0; i < 1000; i++)
{
NotDisposable notDisposable = new NotDisposable();
Disposable disposable = new Disposable();
Disposable disposable = new Disposable();
Disposer<Disposable>.Dispose(disposable);
Disposer<NotDisposable>.Dispose(notDisposable);
}
}

[Benchmark()]
public void GenericDisposerStdCheck()
}
[Benchmark()]
public void GenericDisposerStdCheck()
{
for (int i = 0; i < 1000; i++)
{
for (int i = 0; i < 1000; i++)
{
NotDisposable notDisposable = new NotDisposable();
Disposable disposable = new Disposable();
Disposable disposable = new Disposable();
Disposer2<Disposable>.Dispose(disposable);
Disposer2<NotDisposable>.Dispose(notDisposable);
}
}
}

public static class Disposer<T>
{
// try using a static readonly field
private static readonly bool shouldDispose = typeof(IDisposable).IsAssignableFrom(typeof(T));

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Dispose(T value)
{
if (shouldDispose)
{
((IDisposable)value).Dispose();
}
}
}

}
}
public static class Disposer<T>
{
// try using a static readonly field
private static readonly bool shouldDispose = typeof(IDisposable).IsAssignableFrom(typeof(T));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Dispose(T value)
{
if (shouldDispose)
{
((IDisposable)value).Dispose();
}
}
}
public static class Disposer2<T>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Dispose(T value)
{
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Dispose(T value)
{
if (value is IDisposable d)
{
d.Dispose();
}
}
}

public class NotDisposable
}
}
}
public class NotDisposable
{ }

public class Disposable : IDisposable
{
private bool isDisposed = false;

public void Dispose()
{
if (!isDisposed)
this.isDisposed = true;
}
}
}
public class Disposable : IDisposable
{
private bool isDisposed = false;
public void Dispose()
{
if (!isDisposed)
this.isDisposed = true;
}
}
}
26 changes: 18 additions & 8 deletions BitFaster.Caching.Benchmarks/Lru/LruCycleBench.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ namespace BitFaster.Caching.Benchmarks.Lru
// DefaultJob : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT


//| Method | Mean | Error | StdDev | Code Size | Gen 0 | Allocated |
//|------------------- |---------:|---------:|---------:|----------:|-------:|----------:|
//| FastConcurrentLru | 22.61 us | 0.125 us | 0.110 us | 0 KB | 2.1362 | 9 KB |
//| ConcurrentLru | 24.39 us | 0.389 us | 0.364 us | 0 KB | 2.1362 | 9 KB |
//| FastConcurrentTLru | 31.28 us | 0.067 us | 0.062 us | 1 KB | 2.3193 | 10 KB |
//| ConcurrentTLru | 31.75 us | 0.074 us | 0.062 us | 1 KB | 2.3193 | 10 KB |
[DisassemblyDiagnoser(printSource: true)]
//| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Code Size | Allocated |
//|------------------- |---------:|---------:|---------:|------:|--------:|-------:|----------:|----------:|
//| FastConcurrentLru | 23.25 us | 0.128 us | 0.114 us | 1.00 | 0.00 | 2.1362 | 5 KB | 9 KB |
//| ConcurrentLru | 23.78 us | 0.116 us | 0.097 us | 1.02 | 0.01 | 2.1362 | 5 KB | 9 KB |
//| FastConcurrentTLru | 32.17 us | 0.463 us | 0.433 us | 1.38 | 0.02 | 2.3193 | 6 KB | 10 KB |
//| ConcurrentTLru | 32.52 us | 0.386 us | 0.361 us | 1.40 | 0.02 | 2.3193 | 6 KB | 10 KB |
//| ClassicLru | 16.29 us | 0.195 us | 0.163 us | 0.70 | 0.01 | 3.2959 | 5 KB | 14 KB |
[DisassemblyDiagnoser(printSource: true, maxDepth: 5)]
[MemoryDiagnoser]
public class LruCycleBench
{
Expand All @@ -31,7 +32,7 @@ public class LruCycleBench
private static readonly FastConcurrentLru<int, int> fastConcurrentLru = new(8, 9, EqualityComparer<int>.Default);
private static readonly FastConcurrentTLru<int, int> fastConcurrentTLru = new(8, 9, EqualityComparer<int>.Default, TimeSpan.FromMinutes(1));

[Benchmark()]
[Benchmark(Baseline = true)]
public void FastConcurrentLru()
{
Func<int, int> func = x => x;
Expand Down Expand Up @@ -66,5 +67,14 @@ public void ConcurrentTLru()
for (int i = 0; i < 128; i++)
concurrentTlru.GetOrAdd(i, func);
}

[Benchmark()]
public void ClassicLru()
{
Func<int, int> func = x => x;

for (int i = 0; i < 128; i++)
classicLru.GetOrAdd(i, func);
}
}
}
18 changes: 9 additions & 9 deletions BitFaster.Caching.Benchmarks/Lru/LruJustGetOrAdd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ namespace BitFaster.Caching.Benchmarks

//| Method | Mean | Error | StdDev | Ratio | RatioSD | Code Size | Gen 0 | Allocated |
//|------------------------- |-----------:|----------:|----------:|------:|--------:|----------:|-------:|----------:|
//| ConcurrentDictionary | 7.761 ns | 0.0393 ns | 0.0307 ns | 1.00 | 0.00 | 340 B | - | - |
//| FastConcurrentLru | 9.559 ns | 0.0625 ns | 0.0585 ns | 1.23 | 0.01 | 427 B | - | - |
//| ConcurrentLru | 13.580 ns | 0.0531 ns | 0.0443 ns | 1.75 | 0.01 | 449 B | - | - |
//| FastConcurrentTLru | 27.109 ns | 0.1041 ns | 0.0813 ns | 3.49 | 0.02 | 613 B | - | - |
//| ConcurrentTLru | 29.622 ns | 0.2369 ns | 0.2216 ns | 3.81 | 0.03 | 684 B | - | - |
//| ClassicLru | 48.060 ns | 0.2447 ns | 0.2169 ns | 6.19 | 0.03 | 738 B | - | - |
//| RuntimeMemoryCacheGet | 106.117 ns | 0.4677 ns | 0.4375 ns | 13.69 | 0.08 | 49 B | 0.0074 | 32 B |
//| ExtensionsMemoryCacheGet | 92.386 ns | 0.4539 ns | 0.4023 ns | 11.91 | 0.07 | 78 B | 0.0055 | 24 B |
[DisassemblyDiagnoser(printSource: true)]
//| ConcurrentDictionary | 7.868 ns | 0.0543 ns | 0.0481 ns | 1.00 | 0.00 | 1,523 B | - | - |
//| FastConcurrentLru | 10.340 ns | 0.0496 ns | 0.0464 ns | 1.31 | 0.01 | 2,185 B | - | - |
//| ConcurrentLru | 13.739 ns | 0.0979 ns | 0.0916 ns | 1.75 | 0.01 | 2,207 B | - | - |
//| FastConcurrentTLru | 25.820 ns | 0.0933 ns | 0.0729 ns | 3.28 | 0.02 | 2,371 B | - | - |
//| ConcurrentTLru | 29.732 ns | 0.1387 ns | 0.1229 ns | 3.78 | 0.03 | 2,442 B | - | - |
//| ClassicLru | 49.041 ns | 0.8575 ns | 0.8021 ns | 6.23 | 0.11 | 3,013 B | - | - |
//| RuntimeMemoryCacheGet | 107.769 ns | 1.1901 ns | 0.9938 ns | 13.69 | 0.15 | 49 B | 0.0074 | 32 B |
//| ExtensionsMemoryCacheGet | 93.188 ns | 0.2321 ns | 0.2171 ns | 11.85 | 0.07 | 78 B | 0.0055 | 24 B |
[DisassemblyDiagnoser(printSource: true, maxDepth: 5)]
[MemoryDiagnoser]
public class LruJustGetOrAdd
{
Expand Down
8 changes: 4 additions & 4 deletions BitFaster.Caching.Benchmarks/Lru/LruJustTryGet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ namespace BitFaster.Caching.Benchmarks.Lru

//| Method | Mean | Error | StdDev | Ratio | RatioSD | Code Size | Allocated |
//|--------------------- |----------:|----------:|----------:|------:|--------:|----------:|----------:|
//| ConcurrentDictionary | 4.421 ns | 0.0295 ns | 0.0276 ns | 1.00 | 0.00 | 364 B | - |
//| FastConcurrentLru | 7.645 ns | 0.0339 ns | 0.0300 ns | 1.73 | 0.02 | 339 B | - |
//| FastConcurrentTLru | 26.139 ns | 0.0741 ns | 0.0619 ns | 5.92 | 0.04 | 437 B | - |
[DisassemblyDiagnoser(printSource: true)]
//| ConcurrentDictionary | 4.480 ns | 0.0230 ns | 0.0204 ns | 1.00 | 0.00 | 364 B | - |
//| FastConcurrentLru | 7.705 ns | 0.0343 ns | 0.0286 ns | 1.72 | 0.01 | 448 B | - |
//| FastConcurrentTLru | 25.350 ns | 0.3301 ns | 0.3088 ns | 5.66 | 0.08 | 546 B | - |
[DisassemblyDiagnoser(printSource: true, maxDepth: 5)]
[MemoryDiagnoser]
public class LruJustTryGet
{
Expand Down
18 changes: 17 additions & 1 deletion BitFaster.Caching.Benchmarks/Lru/LruMultiGet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,23 @@

namespace BitFaster.Caching.Benchmarks.Lru
{
[DisassemblyDiagnoser(printSource: true)]
//BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
//Intel Xeon W-2133 CPU 3.60GHz, 1 CPU, 12 logical and 6 physical cores
//.NET SDK= 6.0.100
// [Host] : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
// DefaultJob : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT


//| Method | Mean | Error | StdDev | Ratio | RatioSD | Code Size | Gen 0 | Allocated |
//|--------------------- |-----------:|----------:|----------:|------:|--------:|----------:|-------:|----------:|
//| ConcurrentDictionary | 8.389 ns | 0.0233 ns | 0.0206 ns | 1.00 | 0.00 | 1,544 B | - | - |
//| FastConcurrentLru | 10.637 ns | 0.0808 ns | 0.0755 ns | 1.27 | 0.01 | 3,149 B | - | - |
//| ConcurrentLru | 13.977 ns | 0.0674 ns | 0.0526 ns | 1.67 | 0.01 | 3,171 B | - | - |
//| FastConcurrentTLru | 27.107 ns | 0.0810 ns | 0.0632 ns | 3.23 | 0.01 | 3,468 B | - | - |
//| ConcurrentTLru | 33.733 ns | 0.6613 ns | 0.6791 ns | 4.02 | 0.09 | 3,539 B | - | - |
//| ClassicLru | 52.898 ns | 0.3079 ns | 0.2404 ns | 6.30 | 0.03 | 3,021 B | - | - |
//| MemoryCache | 117.075 ns | 1.7664 ns | 1.5658 ns | 13.96 | 0.18 | 94 B | 0.0073 | 32 B |
[DisassemblyDiagnoser(printSource: true, maxDepth: 5)]
[MemoryDiagnoser]
public class LruMultiGet
{
Expand Down
12 changes: 6 additions & 6 deletions BitFaster.Caching.Benchmarks/Lru/LruZipDistribution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ namespace BitFaster.Caching.Benchmarks.Lru

//| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Code Size | Allocated |
//|------------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|----------:|
//| ClassicLru | 108.4 ns | 0.26 ns | 0.20 ns | 1.00 | 0.00 | 0.0154 | 799 B | 67 B |
//| FastConcurrentLru | 123.1 ns | 0.97 ns | 0.86 ns | 1.14 | 0.01 | 0.0093 | 488 B | 41 B |
//| ConcurrentLru | 128.7 ns | 2.12 ns | 1.98 ns | 1.19 | 0.02 | 0.0093 | 510 B | 40 B |
//| FastConcurrentTLru | 166.1 ns | 0.99 ns | 0.83 ns | 1.53 | 0.01 | 0.0100 | 674 B | 43 B |
//| ConcurrentTLru | 172.2 ns | 0.52 ns | 0.46 ns | 1.59 | 0.00 | 0.0103 | 745 B | 45 B |
[DisassemblyDiagnoser(printSource: true)]
//| ClassicLru | 111.3 ns | 1.33 ns | 1.11 ns | 1.00 | 0.00 | 0.0148 | 4,108 B | 64 B |
//| FastConcurrentLru | 121.6 ns | 1.45 ns | 1.21 ns | 1.09 | 0.01 | 0.0090 | 5,085 B | 39 B |
//| ConcurrentLru | 127.4 ns | 0.51 ns | 0.48 ns | 1.14 | 0.01 | 0.0093 | 5,107 B | 41 B |
//| FastConcurrentTLru | 175.6 ns | 1.08 ns | 1.01 ns | 1.58 | 0.02 | 0.0100 | 5,911 B | 44 B |
//| ConcurrentTLru | 169.7 ns | 0.86 ns | 0.80 ns | 1.52 | 0.02 | 0.0098 | 5,982 B | 43 B |
[DisassemblyDiagnoser(printSource: true, maxDepth: 5)]
[MemoryDiagnoser]
public class LruZipDistribution
{
Expand Down