Skip to content

Commit 1047813

Browse files
bitfasteralexpeck
and
alexpeck
authored
update readme (#35)
Co-authored-by: alexpeck <[email protected]>
1 parent 34fec8b commit 1047813

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

README.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ MemoryCache is perfectly servicable. But in some situations, it can be a bottlen
9090

9191
# Performance
9292

93-
## Lru Hit rate
93+
## ConcurrentLru Hit rate
9494

9595
The charts below show the relative hit rate of classic LRU vs Concurrent LRU on a [Zipfian distribution](https://en.wikipedia.org/wiki/Zipf%27s_law) of input keys, with parameter *s* = 0.5 and *s* = 0.86 respectively. If there are *N* items, the probability of accessing an item numbered *i* or less is (*i* / *N*)^*s*.
9696

9797
Here *N* = 50000, and we take 1 million sample keys. The hit rate is the number of times we get a cache hit divided by 1 million.
9898
This test was repeated with the cache configured to different sizes expressed as a percentage *N* (e.g. 10% would be a cache with a capacity 5000).
9999

100-
When the cache is small, below 15% of the total key space, ConcurrentLru outperforms ClassicLru.
100+
When the cache is small, below 15% of the total key space, ConcurrentLru outperforms Lru. In the best case, for *s*=0.5, when the cache is 2.5% of the total key space ConcurrentLru outperforms LRU by more than 50%.
101101

102102
<table>
103103
<tr>
@@ -110,14 +110,16 @@ When the cache is small, below 15% of the total key space, ConcurrentLru outperf
110110
</tr>
111111
</table>
112112

113-
## Lru Benchmarks
113+
## ConcurrentLru Benchmarks
114114

115115
In the benchmarks, a cache miss is essentially free. These tests exist purely to compare the raw execution speed of the cache code. In a real setting, where a cache miss is presumably quite expensive, the relative overhead of the cache will be very small.
116116

117117
Benchmarks are based on BenchmarkDotNet, so are single threaded. The ConcurrentLru family of classes can outperform ClassicLru in multithreaded workloads.
118118

119+
All benchmarks below are run on this measly laptop:
120+
119121
~~~
120-
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.900 (1909/November2018Update/19H2)
122+
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.264 (2004/?/20H1)
121123
Intel Core i7-5600U CPU 2.60GHz (Broadwell), 1 CPU, 4 logical and 2 physical cores
122124
.NET Core SDK=3.1.301
123125
[Host] : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT
@@ -135,7 +137,6 @@ Take 1000 samples of a [Zipfian distribution](https://en.wikipedia.org/wiki/Zipf
135137

136138
Cache size = *N* / 10 (so we can cache 10% of the total set). ConcurrentLru has approximately the same performance as ClassicLru in this single threaded test.
137139

138-
139140
| Method | Mean | Error | StdDev | Ratio | RatioSD |
140141
|------------------- |---------:|--------:|--------:|------:|--------:|
141142
| ClassicLru | 176.1 ns | 2.74 ns | 2.56 ns | 1.00 | 0.00 |
@@ -156,13 +157,14 @@ FastConcurrentLru does not allocate and is approximately 10x faster than MemoryC
156157

157158
| Method | Mean | Error | StdDev | Ratio | Gen 0 | Allocated |
158159
|--------------------- |----------:|---------:|---------:|------:|-------:|----------:|
159-
| ConcurrentDictionary | 15.83 ns | 0.242 ns | 0.215 ns | 1.00 | - | - |
160-
| FastConcurrentLru | 20.42 ns | 0.319 ns | 0.283 ns | 1.29 | - | - |
161-
| ConcurrentLru | 24.59 ns | 0.484 ns | 0.594 ns | 1.56 | - | - |
162-
| FastConcurrentTLru | 110.76 ns | 0.664 ns | 0.518 ns | 6.98 | - | - |
163-
| ConcurrentTLru | 114.99 ns | 1.652 ns | 1.465 ns | 7.27 | - | - |
164-
| ClassicLru | 69.01 ns | 0.503 ns | 0.446 ns | 4.36 | - | - |
165-
| MemoryCache | 257.83 ns | 4.786 ns | 4.700 ns | 16.30 | 0.0153 | 32 B |
160+
| ConcurrentDictionary | 15.06 ns | 0.286 ns | 0.307 ns | 1.00 | - | - |
161+
| FastConcurrentLru | 20.70 ns | 0.276 ns | 0.258 ns | 1.37 | - | - |
162+
| ConcurrentLru | 24.09 ns | 0.270 ns | 0.253 ns | 1.60 | - | - |
163+
| FastConcurrentTLru | 49.57 ns | 0.619 ns | 0.517 ns | 3.30 | - | - |
164+
| ConcurrentTLru | 64.82 ns | 2.547 ns | 7.391 ns | 4.50 | - | - |
165+
| ClassicLru | 76.78 ns | 1.412 ns | 3.039 ns | 5.25 | - | - |
166+
| MemoryCache | 278.37 ns | 3.887 ns | 3.035 ns | 18.50 | 0.0153 | 32 B |
167+
166168

167169
## Meta-programming using structs for JIT dead code removal and inlining
168170

0 commit comments

Comments
 (0)