From 020317cd0a0214b65662a5bbc7a96259ba89fd7d Mon Sep 17 00:00:00 2001 From: alexpeck Date: Tue, 16 Jun 2020 01:22:11 -0700 Subject: [PATCH 1/3] clean --- ...nchmarks.cs => DataStructureBenchmarks.cs} | 8 +- BitFaster.Caching.Benchmarks/Lru/LruCycle.cs | 302 ------------------ .../Lru/{LruGetOrAddTest.cs => LruJustGet.cs} | 2 +- .../Lru/{LruCycle2.cs => LruMultiGet.cs} | 107 ++++--- ...pDistribution.cs => LruZipDistribution.cs} | 2 +- .../Lru/MissHitHitRemove.cs | 120 ------- .../Lru/TLruTimeBenchmark.cs | 3 + BitFaster.Caching.Benchmarks/Program.cs | 4 +- 8 files changed, 67 insertions(+), 481 deletions(-) rename BitFaster.Caching.Benchmarks/{PrimitiveBenchmarks.cs => DataStructureBenchmarks.cs} (91%) delete mode 100644 BitFaster.Caching.Benchmarks/Lru/LruCycle.cs rename BitFaster.Caching.Benchmarks/Lru/{LruGetOrAddTest.cs => LruJustGet.cs} (98%) rename BitFaster.Caching.Benchmarks/Lru/{LruCycle2.cs => LruMultiGet.cs} (55%) rename BitFaster.Caching.Benchmarks/Lru/{ZipDistribution.cs => LruZipDistribution.cs} (98%) delete mode 100644 BitFaster.Caching.Benchmarks/Lru/MissHitHitRemove.cs diff --git a/BitFaster.Caching.Benchmarks/PrimitiveBenchmarks.cs b/BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs similarity index 91% rename from BitFaster.Caching.Benchmarks/PrimitiveBenchmarks.cs rename to BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs index 2a38f341..ff085a89 100644 --- a/BitFaster.Caching.Benchmarks/PrimitiveBenchmarks.cs +++ b/BitFaster.Caching.Benchmarks/DataStructureBenchmarks.cs @@ -10,7 +10,7 @@ namespace BitFaster.Caching.Benchmarks { [MemoryDiagnoser] - public class PrimitiveBenchmarks + public class DataStructureBenchmarks { private static readonly ConcurrentDictionary dictionary = new ConcurrentDictionary(8, 9, EqualityComparer.Default); LinkedList intList = new LinkedList(new int[] { 1, 2, 3 }); @@ -45,12 +45,6 @@ public void LinkedListLockSwapFirstToLast() } } - [Benchmark()] - public DateTime DateTimeUtcNow() - { - return DateTime.UtcNow; - } - [Benchmark()] public void DictionaryGetOrAdd() { diff --git a/BitFaster.Caching.Benchmarks/Lru/LruCycle.cs b/BitFaster.Caching.Benchmarks/Lru/LruCycle.cs deleted file mode 100644 index a89ddc9b..00000000 --- a/BitFaster.Caching.Benchmarks/Lru/LruCycle.cs +++ /dev/null @@ -1,302 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Columns; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Jobs; -using BitFaster.Caching.Lru; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Runtime.Caching; -using System.Text; - -namespace BitFaster.Caching.Benchmarks.Lru -{ - [MemoryDiagnoser] - public class LruCycle - { - private static readonly ConcurrentDictionary dictionary = new ConcurrentDictionary(8, 9, EqualityComparer.Default); - - private static readonly ClassicLru classicLru = new ClassicLru(8, 9, EqualityComparer.Default); - private static readonly ConcurrentLru concurrentLru = new ConcurrentLru(8, 9, EqualityComparer.Default); - private static readonly ConcurrentTLru concurrentTLru = new ConcurrentTLru(8, 9, EqualityComparer.Default, TimeSpan.FromMinutes(1)); - private static readonly FastConcurrentLru fastConcurrentLru = new FastConcurrentLru(8, 9, EqualityComparer.Default); - private static readonly FastConcurrentTLru fastConcurrentTLru = new FastConcurrentTLru(8, 9, EqualityComparer.Default, TimeSpan.FromMinutes(1)); - - private static MemoryCache memoryCache = System.Runtime.Caching.MemoryCache.Default; - - [GlobalSetup] - public void GlobalSetup() - { - Func func = x => x; - - dictionary.GetOrAdd(1, func); - dictionary.GetOrAdd(2, func); - dictionary.GetOrAdd(3, func); - dictionary.GetOrAdd(4, func); - dictionary.GetOrAdd(5, func); - dictionary.GetOrAdd(6, func); - - memoryCache.Set("1", "test", new CacheItemPolicy()); - memoryCache.Set("2", "test", new CacheItemPolicy()); - memoryCache.Set("3", "test", new CacheItemPolicy()); - memoryCache.Set("4", "test", new CacheItemPolicy()); - memoryCache.Set("5", "test", new CacheItemPolicy()); - memoryCache.Set("6", "test", new CacheItemPolicy()); - - classicLru.GetOrAdd(1, func); - classicLru.GetOrAdd(2, func); - classicLru.GetOrAdd(3, func); - classicLru.GetOrAdd(4, func); - classicLru.GetOrAdd(5, func); - classicLru.GetOrAdd(6, func); - - concurrentLru.GetOrAdd(1, func); - concurrentLru.GetOrAdd(2, func); - concurrentLru.GetOrAdd(3, func); - concurrentLru.GetOrAdd(4, func); - concurrentLru.GetOrAdd(5, func); - concurrentLru.GetOrAdd(6, func); - - } - - [Benchmark(Baseline = true, OperationsPerInvoke = 24)] - public void ConcurrentDictionary() - { - Func func = x => x; - dictionary.GetOrAdd(1, func); - dictionary.GetOrAdd(2, func); - dictionary.GetOrAdd(3, func); - dictionary.GetOrAdd(4, func); - dictionary.GetOrAdd(5, func); - dictionary.GetOrAdd(6, func); - - dictionary.GetOrAdd(1, func); - dictionary.GetOrAdd(2, func); - dictionary.GetOrAdd(3, func); - dictionary.GetOrAdd(4, func); - dictionary.GetOrAdd(5, func); - dictionary.GetOrAdd(6, func); - - dictionary.GetOrAdd(1, func); - dictionary.GetOrAdd(2, func); - dictionary.GetOrAdd(3, func); - dictionary.GetOrAdd(4, func); - dictionary.GetOrAdd(5, func); - dictionary.GetOrAdd(6, func); - - dictionary.GetOrAdd(1, func); - dictionary.GetOrAdd(2, func); - dictionary.GetOrAdd(3, func); - dictionary.GetOrAdd(4, func); - dictionary.GetOrAdd(5, func); - dictionary.GetOrAdd(6, func); - } - - [Benchmark(OperationsPerInvoke = 24)] - public void FastConcurrentLru() - { - // size is 9, so segment size is 3. 6 items will cause queue cycling - // without eviction. Hot => cold when not accessed. - Func func = x => x; - fastConcurrentLru.GetOrAdd(1, func); - fastConcurrentLru.GetOrAdd(2, func); - fastConcurrentLru.GetOrAdd(3, func); - fastConcurrentLru.GetOrAdd(4, func); - fastConcurrentLru.GetOrAdd(5, func); - fastConcurrentLru.GetOrAdd(6, func); - - fastConcurrentLru.GetOrAdd(1, func); - fastConcurrentLru.GetOrAdd(2, func); - fastConcurrentLru.GetOrAdd(3, func); - fastConcurrentLru.GetOrAdd(4, func); - fastConcurrentLru.GetOrAdd(5, func); - fastConcurrentLru.GetOrAdd(6, func); - - fastConcurrentLru.GetOrAdd(1, func); - fastConcurrentLru.GetOrAdd(2, func); - fastConcurrentLru.GetOrAdd(3, func); - fastConcurrentLru.GetOrAdd(4, func); - fastConcurrentLru.GetOrAdd(5, func); - fastConcurrentLru.GetOrAdd(6, func); - - fastConcurrentLru.GetOrAdd(1, func); - fastConcurrentLru.GetOrAdd(2, func); - fastConcurrentLru.GetOrAdd(3, func); - fastConcurrentLru.GetOrAdd(4, func); - fastConcurrentLru.GetOrAdd(5, func); - fastConcurrentLru.GetOrAdd(6, func); - } - - [Benchmark(OperationsPerInvoke = 24)] - public void ConcurrentLru() - { - // size is 9, so segment size is 3. 6 items will cause queue cycling - // without eviction. Hot => cold when not accessed. - Func func = x => x; - concurrentLru.GetOrAdd(1, func); - concurrentLru.GetOrAdd(2, func); - concurrentLru.GetOrAdd(3, func); - concurrentLru.GetOrAdd(4, func); - concurrentLru.GetOrAdd(5, func); - concurrentLru.GetOrAdd(6, func); - - concurrentLru.GetOrAdd(1, func); - concurrentLru.GetOrAdd(2, func); - concurrentLru.GetOrAdd(3, func); - concurrentLru.GetOrAdd(4, func); - concurrentLru.GetOrAdd(5, func); - concurrentLru.GetOrAdd(6, func); - - concurrentLru.GetOrAdd(1, func); - concurrentLru.GetOrAdd(2, func); - concurrentLru.GetOrAdd(3, func); - concurrentLru.GetOrAdd(4, func); - concurrentLru.GetOrAdd(5, func); - concurrentLru.GetOrAdd(6, func); - - concurrentLru.GetOrAdd(1, func); - concurrentLru.GetOrAdd(2, func); - concurrentLru.GetOrAdd(3, func); - concurrentLru.GetOrAdd(4, func); - concurrentLru.GetOrAdd(5, func); - concurrentLru.GetOrAdd(6, func); - } - - [Benchmark(OperationsPerInvoke = 24)] - public void FastConcurrentTLru() - { - // size is 9, so segment size is 3. 6 items will cause queue cycling - // without eviction. Hot => cold when not accessed. - Func func = x => x; - fastConcurrentTLru.GetOrAdd(1, func); - fastConcurrentTLru.GetOrAdd(2, func); - fastConcurrentTLru.GetOrAdd(3, func); - fastConcurrentTLru.GetOrAdd(4, func); - fastConcurrentTLru.GetOrAdd(5, func); - fastConcurrentTLru.GetOrAdd(6, func); - - fastConcurrentTLru.GetOrAdd(1, func); - fastConcurrentTLru.GetOrAdd(2, func); - fastConcurrentTLru.GetOrAdd(3, func); - fastConcurrentTLru.GetOrAdd(4, func); - fastConcurrentTLru.GetOrAdd(5, func); - fastConcurrentTLru.GetOrAdd(6, func); - - fastConcurrentTLru.GetOrAdd(1, func); - fastConcurrentTLru.GetOrAdd(2, func); - fastConcurrentTLru.GetOrAdd(3, func); - fastConcurrentTLru.GetOrAdd(4, func); - fastConcurrentTLru.GetOrAdd(5, func); - fastConcurrentTLru.GetOrAdd(6, func); - - fastConcurrentTLru.GetOrAdd(1, func); - fastConcurrentTLru.GetOrAdd(2, func); - fastConcurrentTLru.GetOrAdd(3, func); - fastConcurrentTLru.GetOrAdd(4, func); - fastConcurrentTLru.GetOrAdd(5, func); - fastConcurrentTLru.GetOrAdd(6, func); - } - - [Benchmark(OperationsPerInvoke = 24)] - public void ConcurrentTLru() - { - // size is 9, so segment size is 3. 6 items will cause queue cycling - // without eviction. Hot => cold when not accessed. - Func func = x => x; - concurrentTLru.GetOrAdd(1, func); - concurrentTLru.GetOrAdd(2, func); - concurrentTLru.GetOrAdd(3, func); - concurrentTLru.GetOrAdd(4, func); - concurrentTLru.GetOrAdd(5, func); - concurrentTLru.GetOrAdd(6, func); - - concurrentTLru.GetOrAdd(1, func); - concurrentTLru.GetOrAdd(2, func); - concurrentTLru.GetOrAdd(3, func); - concurrentTLru.GetOrAdd(4, func); - concurrentTLru.GetOrAdd(5, func); - concurrentTLru.GetOrAdd(6, func); - - concurrentTLru.GetOrAdd(1, func); - concurrentTLru.GetOrAdd(2, func); - concurrentTLru.GetOrAdd(3, func); - concurrentTLru.GetOrAdd(4, func); - concurrentTLru.GetOrAdd(5, func); - concurrentTLru.GetOrAdd(6, func); - - concurrentTLru.GetOrAdd(1, func); - concurrentTLru.GetOrAdd(2, func); - concurrentTLru.GetOrAdd(3, func); - concurrentTLru.GetOrAdd(4, func); - concurrentTLru.GetOrAdd(5, func); - concurrentTLru.GetOrAdd(6, func); - } - - [Benchmark(OperationsPerInvoke = 24)] - public void ClassicLru() - { - // size is 9, so segment size is 3. 6 items will cause queue cycling - // without eviction. Hot => cold when not accessed. - Func func = x => x; - classicLru.GetOrAdd(1, func); - classicLru.GetOrAdd(2, func); - classicLru.GetOrAdd(3, func); - classicLru.GetOrAdd(4, func); - classicLru.GetOrAdd(5, func); - classicLru.GetOrAdd(6, func); - - classicLru.GetOrAdd(1, func); - classicLru.GetOrAdd(2, func); - classicLru.GetOrAdd(3, func); - classicLru.GetOrAdd(4, func); - classicLru.GetOrAdd(5, func); - classicLru.GetOrAdd(6, func); - - classicLru.GetOrAdd(1, func); - classicLru.GetOrAdd(2, func); - classicLru.GetOrAdd(3, func); - classicLru.GetOrAdd(4, func); - classicLru.GetOrAdd(5, func); - classicLru.GetOrAdd(6, func); - - classicLru.GetOrAdd(1, func); - classicLru.GetOrAdd(2, func); - classicLru.GetOrAdd(3, func); - classicLru.GetOrAdd(4, func); - classicLru.GetOrAdd(5, func); - classicLru.GetOrAdd(6, func); - } - - [Benchmark(OperationsPerInvoke = 24)] - public void MemoryCache() - { - memoryCache.Get("1"); - memoryCache.Get("2"); - memoryCache.Get("3"); - memoryCache.Get("4"); - memoryCache.Get("5"); - memoryCache.Get("6"); - - memoryCache.Get("1"); - memoryCache.Get("2"); - memoryCache.Get("3"); - memoryCache.Get("4"); - memoryCache.Get("5"); - memoryCache.Get("6"); - - memoryCache.Get("1"); - memoryCache.Get("2"); - memoryCache.Get("3"); - memoryCache.Get("4"); - memoryCache.Get("5"); - memoryCache.Get("6"); - - memoryCache.Get("1"); - memoryCache.Get("2"); - memoryCache.Get("3"); - memoryCache.Get("4"); - memoryCache.Get("5"); - memoryCache.Get("6"); - } - } -} diff --git a/BitFaster.Caching.Benchmarks/Lru/LruGetOrAddTest.cs b/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs similarity index 98% rename from BitFaster.Caching.Benchmarks/Lru/LruGetOrAddTest.cs rename to BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs index 080ba4f1..fc86b4c7 100644 --- a/BitFaster.Caching.Benchmarks/Lru/LruGetOrAddTest.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs @@ -12,7 +12,7 @@ namespace BitFaster.Caching.Benchmarks { [MemoryDiagnoser] - public class LruGetOrAddTest + public class LruJustGet { private static readonly ConcurrentDictionary dictionary = new ConcurrentDictionary(8, 9, EqualityComparer.Default); diff --git a/BitFaster.Caching.Benchmarks/Lru/LruCycle2.cs b/BitFaster.Caching.Benchmarks/Lru/LruMultiGet.cs similarity index 55% rename from BitFaster.Caching.Benchmarks/Lru/LruCycle2.cs rename to BitFaster.Caching.Benchmarks/Lru/LruMultiGet.cs index 263f2758..5a8f95ca 100644 --- a/BitFaster.Caching.Benchmarks/Lru/LruCycle2.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruMultiGet.cs @@ -3,6 +3,7 @@ using BenchmarkDotNet.Configs; using BenchmarkDotNet.Jobs; using BitFaster.Caching.Lru; +using Microsoft.VisualBasic; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -12,35 +13,50 @@ namespace BitFaster.Caching.Benchmarks.Lru { [MemoryDiagnoser] - public class LruCycle2 + public class LruMultiGet { - const int capacity = 9; - const int iters = 10; - private static readonly ConcurrentDictionary dictionary = new ConcurrentDictionary(8, 9, EqualityComparer.Default); - private static readonly ClassicLru classicLru = new ClassicLru(8, capacity, EqualityComparer.Default); - private static readonly ConcurrentLru concurrentLru = new ConcurrentLru(8, capacity, EqualityComparer.Default); - private static readonly ConcurrentTLru concurrentTLru = new ConcurrentTLru(8, capacity, EqualityComparer.Default, TimeSpan.FromMinutes(1)); - private static readonly FastConcurrentLru fastConcurrentLru = new FastConcurrentLru(8, capacity, EqualityComparer.Default); - private static readonly FastConcurrentTLru fastConcurrentTLru = new FastConcurrentTLru(8, capacity, EqualityComparer.Default, TimeSpan.FromMinutes(1)); + private static readonly ClassicLru classicLru = new ClassicLru(8, 9, EqualityComparer.Default); + private static readonly ConcurrentLru concurrentLru = new ConcurrentLru(8, 9, EqualityComparer.Default); + private static readonly ConcurrentTLru concurrentTLru = new ConcurrentTLru(8, 9, EqualityComparer.Default, TimeSpan.FromMinutes(1)); + private static readonly FastConcurrentLru fastConcurrentLru = new FastConcurrentLru(8, 9, EqualityComparer.Default); + private static readonly FastConcurrentTLru fastConcurrentTLru = new FastConcurrentTLru(8, 9, EqualityComparer.Default, TimeSpan.FromMinutes(1)); private static MemoryCache memoryCache = System.Runtime.Caching.MemoryCache.Default; + private static readonly string[] stringKeys = new string[6]; + + [GlobalSetup] + public void GlobalSetup() + { + Func func = x => x; + + for (int i = 0; i < 6; i++) + { + dictionary.GetOrAdd(1, func); + + concurrentLru.GetOrAdd(i, func); + fastConcurrentLru.GetOrAdd(i, func); + concurrentTLru.GetOrAdd(i, func); + fastConcurrentTLru.GetOrAdd(i, func); + + classicLru.GetOrAdd(i, func); + stringKeys[i] = i.ToString(); + memoryCache.Set(stringKeys[i], "test", new CacheItemPolicy()); + } + } + [Benchmark(Baseline = true, OperationsPerInvoke = 24)] public void ConcurrentDictionary() { Func func = x => x; - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - dictionary.GetOrAdd(i, func); - - // simulate what the LRU does - if (i == capacity) + for (int i = 0; i < 6; i++) { - dictionary.TryRemove(1, out var removed); + dictionary.GetOrAdd(i, func); } } } @@ -50,10 +66,12 @@ public void FastConcurrentLru() { Func func = x => x; - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - fastConcurrentLru.GetOrAdd(i, func); + for (int i = 0; i < 6; i++) + { + fastConcurrentLru.GetOrAdd(i, func); + } } } @@ -62,10 +80,12 @@ public void ConcurrentLru() { Func func = x => x; - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - concurrentLru.GetOrAdd(i, func); + for (int i = 0; i < 6; i++) + { + concurrentLru.GetOrAdd(i, func); + } } } @@ -74,10 +94,12 @@ public void FastConcurrentTLru() { Func func = x => x; - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - fastConcurrentTLru.GetOrAdd(i, func); + for (int i = 0; i < 6; i++) + { + fastConcurrentTLru.GetOrAdd(i, func); + } } } @@ -86,10 +108,12 @@ public void ConcurrentTLru() { Func func = x => x; - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - concurrentTLru.GetOrAdd(i, func); + for (int i = 0; i < 6; i++) + { + concurrentTLru.GetOrAdd(i, func); + } } } @@ -98,34 +122,23 @@ public void ClassicLru() { Func func = x => x; - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - classicLru.GetOrAdd(i, func); + for (int i = 0; i < 6; i++) + { + classicLru.GetOrAdd(1, func); + } } } [Benchmark(OperationsPerInvoke = 24)] public void MemoryCache() { - - Func func = x => x; - - for (int j = 0; j < iters; j++) - for (int i = 0; i < capacity + 1; i++) + for (int j = 0; j < 4; j++) { - string key = i.ToString(); - var v = memoryCache.Get(key); - - if (v == null) - { - memoryCache.Set(key, "test", new CacheItemPolicy()); - } - - // simulate what the LRU does - if (i == capacity) + for (int i = 0; i < 6; i++) { - memoryCache.Remove("1"); + memoryCache.Get(stringKeys[i]); } } } diff --git a/BitFaster.Caching.Benchmarks/Lru/ZipDistribution.cs b/BitFaster.Caching.Benchmarks/Lru/LruZipDistribution.cs similarity index 98% rename from BitFaster.Caching.Benchmarks/Lru/ZipDistribution.cs rename to BitFaster.Caching.Benchmarks/Lru/LruZipDistribution.cs index d69e1321..08349e7f 100644 --- a/BitFaster.Caching.Benchmarks/Lru/ZipDistribution.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruZipDistribution.cs @@ -8,7 +8,7 @@ namespace BitFaster.Caching.Benchmarks.Lru { - public class ZipDistribution + public class LruZipDistribution { const double s = 0.86; const int n = 500; diff --git a/BitFaster.Caching.Benchmarks/Lru/MissHitHitRemove.cs b/BitFaster.Caching.Benchmarks/Lru/MissHitHitRemove.cs deleted file mode 100644 index 704733d1..00000000 --- a/BitFaster.Caching.Benchmarks/Lru/MissHitHitRemove.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Runtime.Caching; -using System.Text; -using BenchmarkDotNet.Attributes; -using BitFaster.Caching.Lru; - -namespace BitFaster.Caching.Benchmarks.Lru -{ - [MemoryDiagnoser] - public class MissHitHitRemove - { - const int capacity = 9; - const int arraySize = 16; - - private static readonly ConcurrentDictionary dictionary = new ConcurrentDictionary(8, capacity, EqualityComparer.Default); - - private static readonly ClassicLru classicLru = new ClassicLru(8, capacity, EqualityComparer.Default); - private static readonly ConcurrentLru concurrentLru = new ConcurrentLru(8, capacity, EqualityComparer.Default); - private static readonly ConcurrentTLru concurrentTlru = new ConcurrentTLru(8, capacity, EqualityComparer.Default, TimeSpan.FromMinutes(10)); - private static readonly FastConcurrentLru fastConcurrentLru = new FastConcurrentLru(8, capacity, EqualityComparer.Default); - private static readonly FastConcurrentTLru fastConcurrentTLru = new FastConcurrentTLru(8, capacity, EqualityComparer.Default, TimeSpan.FromMinutes(1)); - - private static MemoryCache memoryCache = System.Runtime.Caching.MemoryCache.Default; - - [Benchmark(Baseline = true)] - public void ConcurrentDictionary() - { - Func func = x => new byte[arraySize]; - dictionary.GetOrAdd(1, func); - - dictionary.GetOrAdd(1, func); - dictionary.GetOrAdd(1, func); - - dictionary.TryRemove(1, out var removed); - } - - [Benchmark()] - public void FastConcurrentLru() - { - Func func = x => new byte[arraySize]; - fastConcurrentLru.GetOrAdd(1, func); - - fastConcurrentLru.GetOrAdd(1, func); - fastConcurrentLru.GetOrAdd(1, func); - - fastConcurrentLru.TryRemove(1); - } - - [Benchmark()] - public void ConcurrentLru() - { - Func func = x => new byte[arraySize]; - concurrentLru.GetOrAdd(1, func); - - concurrentLru.GetOrAdd(1, func); - concurrentLru.GetOrAdd(1, func); - - concurrentLru.TryRemove(1); - } - - [Benchmark()] - public void FastConcurrentTlru() - { - Func func = x => new byte[arraySize]; - fastConcurrentTLru.GetOrAdd(1, func); - - fastConcurrentTLru.GetOrAdd(1, func); - fastConcurrentTLru.GetOrAdd(1, func); - - fastConcurrentTLru.TryRemove(1); - } - - [Benchmark()] - public void ConcurrentTlru() - { - Func func = x => new byte[arraySize]; - concurrentTlru.GetOrAdd(1, func); - - concurrentTlru.GetOrAdd(1, func); - concurrentTlru.GetOrAdd(1, func); - - concurrentTlru.TryRemove(1); - } - - [Benchmark()] - public void ClassicLru() - { - Func func = x => new byte[arraySize]; - classicLru.GetOrAdd(1, func); - - classicLru.GetOrAdd(1, func); - classicLru.GetOrAdd(1, func); - - classicLru.TryRemove(1); - } - - [Benchmark()] - public void MemoryCache() - { - if (memoryCache.Get("1") == null) - { - memoryCache.Set("1", new byte[arraySize], new CacheItemPolicy()); - } - - if (memoryCache.Get("1") == null) - { - memoryCache.Set("1", new byte[arraySize], new CacheItemPolicy()); - } - - if (memoryCache.Get("1") == null) - { - memoryCache.Set("1", new byte[arraySize], new CacheItemPolicy()); - } - - memoryCache.Remove("1"); - } - } -} diff --git a/BitFaster.Caching.Benchmarks/Lru/TLruTimeBenchmark.cs b/BitFaster.Caching.Benchmarks/Lru/TLruTimeBenchmark.cs index e6f249a2..447dea29 100644 --- a/BitFaster.Caching.Benchmarks/Lru/TLruTimeBenchmark.cs +++ b/BitFaster.Caching.Benchmarks/Lru/TLruTimeBenchmark.cs @@ -6,6 +6,9 @@ namespace BitFaster.Caching.Benchmarks.Lru { + /// + /// Compare different implementations of the TLRU policy. In particular, which clock impl is fastest? + /// public class TLruTimeBenchmark { private static readonly TemplateConcurrentLru, TLruDateTimePolicy, NullHitCounter> dateTimeTLru diff --git a/BitFaster.Caching.Benchmarks/Program.cs b/BitFaster.Caching.Benchmarks/Program.cs index 92018bcf..3f531a9c 100644 --- a/BitFaster.Caching.Benchmarks/Program.cs +++ b/BitFaster.Caching.Benchmarks/Program.cs @@ -14,9 +14,7 @@ class Program { static void Main(string[] args) { - var summary = BenchmarkRunner - .Run(ManualConfig.Create(DefaultConfig.Instance) - .AddJob(Job.RyuJitX64)); + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); } } } From 3ad64ca370df040ee938085e28b6af257639f562 Mon Sep 17 00:00:00 2001 From: alexpeck Date: Tue, 16 Jun 2020 14:13:30 -0700 Subject: [PATCH 2/3] add ext cache --- .../BitFaster.Caching.Benchmarks.csproj | 1 + .../Lru/LruJustGet.cs | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj b/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj index ade8391f..d0367bbc 100644 --- a/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj +++ b/BitFaster.Caching.Benchmarks/BitFaster.Caching.Benchmarks.csproj @@ -16,6 +16,7 @@ + diff --git a/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs b/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs index fc86b4c7..ba1d4580 100644 --- a/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs @@ -1,11 +1,12 @@ using BenchmarkDotNet.Attributes; using BitFaster.Caching; +using BitFaster.Caching.Benchmarks.Lru; using BitFaster.Caching.Lru; +using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Runtime.Caching; using System.Text; using System.Threading.Tasks; @@ -23,12 +24,16 @@ public class LruJustGet private static readonly FastConcurrentTLru fastConcurrentTLru = new FastConcurrentTLru(8, 9, EqualityComparer.Default, TimeSpan.FromMinutes(1)); private static readonly int key = 1; - private static MemoryCache memoryCache = MemoryCache.Default; + private static System.Runtime.Caching.MemoryCache memoryCache = System.Runtime.Caching.MemoryCache.Default; + + Microsoft.Extensions.Caching.Memory.MemoryCache exMemoryCache + = new Microsoft.Extensions.Caching.Memory.MemoryCache(new MemoryCacheOptionsAccessor()); [GlobalSetup] public void GlobalSetup() { - memoryCache.Set(key.ToString(), "test", new CacheItemPolicy()); + memoryCache.Set(key.ToString(), "test", new System.Runtime.Caching.CacheItemPolicy()); + exMemoryCache.Set(key, "test"); } [Benchmark(Baseline = true)] @@ -78,5 +83,20 @@ public void MemoryCacheGetStringKey() { memoryCache.Get("1"); } + + [Benchmark()] + public void ExMemoryCacheGetStringKey() + { + exMemoryCache.Get(1); + } + + public class MemoryCacheOptionsAccessor + : Microsoft.Extensions.Options.IOptions + { + private readonly MemoryCacheOptions options = new MemoryCacheOptions(); + + public MemoryCacheOptions Value => this.options; + + } } } From 5c0bcb97c78333547208f2a873710577768e2177 Mon Sep 17 00:00:00 2001 From: alexpeck Date: Tue, 16 Jun 2020 14:18:28 -0700 Subject: [PATCH 3/3] update names --- .../Lru/LruJustGet.cs | 16 +++++++-------- README.md | 20 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs b/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs index ba1d4580..9859e248 100644 --- a/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruJustGet.cs @@ -37,55 +37,55 @@ public void GlobalSetup() } [Benchmark(Baseline = true)] - public void ConcurrentDictionaryGetOrAdd() + public void ConcurrentDictionary() { Func func = x => x; dictionary.GetOrAdd(1, func); } [Benchmark()] - public void FastConcurrentLruGetOrAdd() + public void FastConcurrentLru() { Func func = x => x; fastConcurrentLru.GetOrAdd(1, func); } [Benchmark()] - public void ConcurrentLruGetOrAdd() + public void ConcurrentLru() { Func func = x => x; concurrentLru.GetOrAdd(1, func); } [Benchmark()] - public void FastConcurrentTLruGetOrAdd() + public void FastConcurrentTLru() { Func func = x => x; fastConcurrentTLru.GetOrAdd(1, func); } [Benchmark()] - public void ConcurrentTLruGetOrAdd() + public void ConcurrentTLru() { Func func = x => x; concurrentTlru.GetOrAdd(1, func); } [Benchmark()] - public void ClassicLruGetOrAdd() + public void ClassicLru() { Func func = x => x; classicLru.GetOrAdd(1, func); } [Benchmark()] - public void MemoryCacheGetStringKey() + public void RuntimeMemoryCacheGet() { memoryCache.Get("1"); } [Benchmark()] - public void ExMemoryCacheGetStringKey() + public void ExtensionsMemoryCacheGet() { exMemoryCache.Get(1); } diff --git a/README.md b/README.md index 82700072..3a21457d 100644 --- a/README.md +++ b/README.md @@ -158,16 +158,16 @@ In this test the same items are fetched repeatedly, no items are evicted. Repres FastConcurrentLru does not allocate and is approximately 10x faster than MemoryCache. -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated | -|--------------------- |----------:|---------:|---------:|------:|-------:|----------:| -| ConcurrentDictionary | 15.06 ns | 0.286 ns | 0.307 ns | 1.00 | - | - | -| FastConcurrentLru | 20.70 ns | 0.276 ns | 0.258 ns | 1.37 | - | - | -| ConcurrentLru | 24.09 ns | 0.270 ns | 0.253 ns | 1.60 | - | - | -| FastConcurrentTLru | 49.57 ns | 0.619 ns | 0.517 ns | 3.30 | - | - | -| ConcurrentTLru | 64.82 ns | 2.547 ns | 7.391 ns | 4.50 | - | - | -| ClassicLru | 76.78 ns | 1.412 ns | 3.039 ns | 5.25 | - | - | -| MemoryCache | 278.37 ns | 3.887 ns | 3.035 ns | 18.50 | 0.0153 | 32 B | - +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated | +|---------------------- |----------:|---------:|---------:|------:|-------:|----------:| +| ConcurrentDictionary | 16.88 ns | 0.276 ns | 0.245 ns | 1.00 | - | - | +| FastConcurrentLru | 23.27 ns | 0.491 ns | 0.565 ns | 1.38 | - | - | +| ConcurrentLru | 26.77 ns | 0.512 ns | 0.666 ns | 1.60 | - | - | +| FastConcurrentTLru | 54.35 ns | 0.650 ns | 0.576 ns | 3.22 | - | - | +| ConcurrentTLru | 60.10 ns | 1.024 ns | 1.501 ns | 3.53 | - | - | +| ClassicLru | 68.04 ns | 1.400 ns | 2.221 ns | 4.12 | - | - | +| RuntimeMemoryCache | 280.16 ns | 5.607 ns | 7.486 ns | 16.59 | 0.0153 | 32 B | +| ExtensionsMemoryCache | 342.72 ns | 3.729 ns | 3.114 ns | 20.29 | 0.0114 | 24 B | ## Meta-programming using structs for JIT dead code removal and inlining