Skip to content

Commit a087d01

Browse files
authored
Benchmark Microsoft.Extensions.Caching.Memory.MemoryCache (#39)
* clean * add ext cache * update names
1 parent 61da73c commit a087d01

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<ItemGroup>
1717
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
1818
<PackageReference Include="MathNet.Numerics" Version="4.11.0" />
19+
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.5" />
1920
<PackageReference Include="System.Runtime.Caching" Version="4.7.0" />
2021
</ItemGroup>
2122

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using BenchmarkDotNet.Attributes;
22
using BitFaster.Caching;
3+
using BitFaster.Caching.Benchmarks.Lru;
34
using BitFaster.Caching.Lru;
5+
using Microsoft.Extensions.Caching.Memory;
46
using System;
57
using System.Collections.Concurrent;
68
using System.Collections.Generic;
79
using System.Linq;
8-
using System.Runtime.Caching;
910
using System.Text;
1011
using System.Threading.Tasks;
1112

@@ -23,60 +24,79 @@ public class LruJustGet
2324
private static readonly FastConcurrentTLru<int, int> fastConcurrentTLru = new FastConcurrentTLru<int, int>(8, 9, EqualityComparer<int>.Default, TimeSpan.FromMinutes(1));
2425

2526
private static readonly int key = 1;
26-
private static MemoryCache memoryCache = MemoryCache.Default;
27+
private static System.Runtime.Caching.MemoryCache memoryCache = System.Runtime.Caching.MemoryCache.Default;
28+
29+
Microsoft.Extensions.Caching.Memory.MemoryCache exMemoryCache
30+
= new Microsoft.Extensions.Caching.Memory.MemoryCache(new MemoryCacheOptionsAccessor());
2731

2832
[GlobalSetup]
2933
public void GlobalSetup()
3034
{
31-
memoryCache.Set(key.ToString(), "test", new CacheItemPolicy());
35+
memoryCache.Set(key.ToString(), "test", new System.Runtime.Caching.CacheItemPolicy());
36+
exMemoryCache.Set(key, "test");
3237
}
3338

3439
[Benchmark(Baseline = true)]
35-
public void ConcurrentDictionaryGetOrAdd()
40+
public void ConcurrentDictionary()
3641
{
3742
Func<int, int> func = x => x;
3843
dictionary.GetOrAdd(1, func);
3944
}
4045

4146
[Benchmark()]
42-
public void FastConcurrentLruGetOrAdd()
47+
public void FastConcurrentLru()
4348
{
4449
Func<int, int> func = x => x;
4550
fastConcurrentLru.GetOrAdd(1, func);
4651
}
4752

4853
[Benchmark()]
49-
public void ConcurrentLruGetOrAdd()
54+
public void ConcurrentLru()
5055
{
5156
Func<int, int> func = x => x;
5257
concurrentLru.GetOrAdd(1, func);
5358
}
5459

5560
[Benchmark()]
56-
public void FastConcurrentTLruGetOrAdd()
61+
public void FastConcurrentTLru()
5762
{
5863
Func<int, int> func = x => x;
5964
fastConcurrentTLru.GetOrAdd(1, func);
6065
}
6166

6267
[Benchmark()]
63-
public void ConcurrentTLruGetOrAdd()
68+
public void ConcurrentTLru()
6469
{
6570
Func<int, int> func = x => x;
6671
concurrentTlru.GetOrAdd(1, func);
6772
}
6873

6974
[Benchmark()]
70-
public void ClassicLruGetOrAdd()
75+
public void ClassicLru()
7176
{
7277
Func<int, int> func = x => x;
7378
classicLru.GetOrAdd(1, func);
7479
}
7580

7681
[Benchmark()]
77-
public void MemoryCacheGetStringKey()
82+
public void RuntimeMemoryCacheGet()
7883
{
7984
memoryCache.Get("1");
8085
}
86+
87+
[Benchmark()]
88+
public void ExtensionsMemoryCacheGet()
89+
{
90+
exMemoryCache.Get(1);
91+
}
92+
93+
public class MemoryCacheOptionsAccessor
94+
: Microsoft.Extensions.Options.IOptions<MemoryCacheOptions>
95+
{
96+
private readonly MemoryCacheOptions options = new MemoryCacheOptions();
97+
98+
public MemoryCacheOptions Value => this.options;
99+
100+
}
81101
}
82102
}

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,16 @@ In this test the same items are fetched repeatedly, no items are evicted. Repres
158158

159159
FastConcurrentLru does not allocate and is approximately 10x faster than MemoryCache.
160160

161-
| Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated |
162-
|--------------------- |----------:|---------:|---------:|------:|-------:|----------:|
163-
| ConcurrentDictionary | 15.06 ns | 0.286 ns | 0.307 ns | 1.00 | - | - |
164-
| FastConcurrentLru | 20.70 ns | 0.276 ns | 0.258 ns | 1.37 | - | - |
165-
| ConcurrentLru | 24.09 ns | 0.270 ns | 0.253 ns | 1.60 | - | - |
166-
| FastConcurrentTLru | 49.57 ns | 0.619 ns | 0.517 ns | 3.30 | - | - |
167-
| ConcurrentTLru | 64.82 ns | 2.547 ns | 7.391 ns | 4.50 | - | - |
168-
| ClassicLru | 76.78 ns | 1.412 ns | 3.039 ns | 5.25 | - | - |
169-
| MemoryCache | 278.37 ns | 3.887 ns | 3.035 ns | 18.50 | 0.0153 | 32 B |
170-
161+
| Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated |
162+
|---------------------- |----------:|---------:|---------:|------:|-------:|----------:|
163+
| ConcurrentDictionary | 16.88 ns | 0.276 ns | 0.245 ns | 1.00 | - | - |
164+
| FastConcurrentLru | 23.27 ns | 0.491 ns | 0.565 ns | 1.38 | - | - |
165+
| ConcurrentLru | 26.77 ns | 0.512 ns | 0.666 ns | 1.60 | - | - |
166+
| FastConcurrentTLru | 54.35 ns | 0.650 ns | 0.576 ns | 3.22 | - | - |
167+
| ConcurrentTLru | 60.10 ns | 1.024 ns | 1.501 ns | 3.53 | - | - |
168+
| ClassicLru | 68.04 ns | 1.400 ns | 2.221 ns | 4.12 | - | - |
169+
| RuntimeMemoryCache | 280.16 ns | 5.607 ns | 7.486 ns | 16.59 | 0.0153 | 32 B |
170+
| ExtensionsMemoryCache | 342.72 ns | 3.729 ns | 3.114 ns | 20.29 | 0.0114 | 24 B |
171171

172172
## Meta-programming using structs for JIT dead code removal and inlining
173173

0 commit comments

Comments
 (0)