Skip to content

Commit e4fe6df

Browse files
authored
thru (#247)
* thru * cleanup * off1 * tindex * col * tc * fmt
1 parent 9079209 commit e4fe6df

File tree

9 files changed

+501
-154
lines changed

9 files changed

+501
-154
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using BitFaster.Caching.Lfu;
8+
using BitFaster.Caching.Lru;
9+
using BitFaster.Caching.Scheduler;
10+
11+
namespace BitFaster.Caching.ThroughputAnalysis
12+
{
13+
public interface ICacheFactory
14+
{
15+
(IScheduler, ICache<int, int>) Create(int threadCount);
16+
17+
public string Name { get; }
18+
19+
DataRow DataRow { get; set; }
20+
}
21+
22+
public class FastConcurrentLruFactory : ICacheFactory
23+
{
24+
private int capacity;
25+
26+
public FastConcurrentLruFactory(int capacity)
27+
{
28+
this.capacity = capacity;
29+
}
30+
31+
public string Name => "FsTConcLRU";
32+
33+
public DataRow DataRow { get; set; }
34+
35+
public (IScheduler, ICache<int, int>) Create(int threadCount)
36+
{
37+
var cache = new FastConcurrentLru<int, int>(threadCount, capacity, EqualityComparer<int>.Default);
38+
39+
return (null, cache);
40+
}
41+
}
42+
43+
public class ConcurrentLruFactory : ICacheFactory
44+
{
45+
private int capacity;
46+
47+
public ConcurrentLruFactory(int capacity)
48+
{
49+
this.capacity = capacity;
50+
}
51+
52+
public string Name => "ConcurrLRU";
53+
54+
public DataRow DataRow { get; set; }
55+
56+
public (IScheduler, ICache<int, int>) Create(int threadCount)
57+
{
58+
var cache = new ConcurrentLru<int, int>(threadCount, capacity, EqualityComparer<int>.Default);
59+
60+
return (null, cache);
61+
}
62+
}
63+
64+
public class MemoryCacheFactory : ICacheFactory
65+
{
66+
private int capacity;
67+
68+
public MemoryCacheFactory(int capacity)
69+
{
70+
this.capacity = capacity;
71+
}
72+
73+
public string Name => "MemryCache";
74+
75+
public DataRow DataRow { get; set; }
76+
77+
public (IScheduler, ICache<int, int>) Create(int threadCount)
78+
{
79+
var cache = new MemoryCacheAdaptor<int, int>(capacity);
80+
81+
return (null, cache);
82+
}
83+
}
84+
85+
public class ConcurrentLfuFactory : ICacheFactory
86+
{
87+
private int capacity;
88+
89+
public ConcurrentLfuFactory(int capacity)
90+
{
91+
this.capacity = capacity;
92+
}
93+
94+
public string Name => "ConcurrLFU";
95+
96+
public DataRow DataRow { get; set; }
97+
98+
public (IScheduler, ICache<int, int>) Create(int threadCount)
99+
{
100+
var scheduler = new BackgroundThreadScheduler();
101+
var cache = new ConcurrentLfu<int, int>(
102+
concurrencyLevel: threadCount,
103+
capacity: capacity,
104+
scheduler: scheduler,
105+
EqualityComparer<int>.Default);
106+
107+
return (scheduler, cache);
108+
}
109+
}
110+
111+
public class ClassicLruFactory : ICacheFactory
112+
{
113+
private int capacity;
114+
115+
public ClassicLruFactory(int capacity)
116+
{
117+
this.capacity = capacity;
118+
}
119+
120+
public string Name => "ClassicLru";
121+
122+
public DataRow DataRow { get; set; }
123+
124+
public (IScheduler, ICache<int, int>) Create(int threadCount)
125+
{
126+
var cache = new ClassicLru<int, int>(threadCount, capacity, EqualityComparer<int>.Default);
127+
128+
return (null, cache);
129+
}
130+
}
131+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BitFaster.Caching.ThroughputAnalysis
8+
{
9+
public class ConfigFactory
10+
{
11+
const double s = 0.86; // Zipf s parameter, controls distribution
12+
const int n = 500; // number of unique items for Zipf
13+
const int maxThreads = 52;
14+
const int sampleCount = 2000;
15+
16+
public static (ThroughputBenchmarkBase, IThroughputBenchConfig, int) Create(Mode mode, int repeatCount)
17+
{
18+
switch (mode)
19+
{
20+
case Mode.Read:
21+
return (new ReadThroughputBenchmark(), new ZipfConfig(repeatCount, sampleCount, s, n), n);
22+
case Mode.ReadWrite:
23+
// cache holds 10% of all items
24+
return (new ReadThroughputBenchmark(), new ZipfConfig(repeatCount, sampleCount, s, n), n / 10);
25+
case Mode.Update:
26+
return (new UpdateThroughputBenchmark(), new ZipfConfig(repeatCount, sampleCount, s, n), n);
27+
case Mode.Evict:
28+
return (new ReadThroughputBenchmark(), new EvictionConfig(repeatCount, sampleCount, maxThreads), n);
29+
}
30+
31+
throw new InvalidOperationException();
32+
}
33+
}
34+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data;
4+
using System.Globalization;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
using CsvHelper;
10+
11+
namespace BitFaster.Caching.ThroughputAnalysis
12+
{
13+
public class Exporter
14+
{
15+
DataTable resultTable = new DataTable();
16+
17+
public Exporter(int maxThreads)
18+
{
19+
// output:
20+
// ThreadCount 1 2 3 4 5
21+
// Classic 5 6 7 7 8
22+
// Concurrent 5 6 7 7 8
23+
24+
resultTable.Clear();
25+
resultTable.Columns.Add("ThreadCount");
26+
foreach (var tc in Enumerable.Range(1, maxThreads).ToArray())
27+
{
28+
resultTable.Columns.Add(tc.ToString());
29+
}
30+
}
31+
32+
public void Initialize(IEnumerable<ICacheFactory> caches)
33+
{
34+
foreach (var c in caches)
35+
{
36+
c.DataRow = resultTable.NewRow();
37+
c.DataRow["ThreadCount"] = c.Name;
38+
}
39+
}
40+
41+
public void CaptureRows(IEnumerable<ICacheFactory> caches)
42+
{
43+
foreach (var c in caches)
44+
{
45+
resultTable.Rows.Add(c.DataRow);
46+
}
47+
}
48+
49+
public void ExportCsv(Mode mode)
50+
{
51+
using (var textWriter = File.CreateText($"Results{mode}.csv"))
52+
using (var csv = new CsvWriter(textWriter, CultureInfo.InvariantCulture))
53+
{
54+
foreach (DataColumn column in resultTable.Columns)
55+
{
56+
csv.WriteField(column.ColumnName);
57+
}
58+
csv.NextRecord();
59+
60+
foreach (DataRow row in resultTable.Rows)
61+
{
62+
for (var i = 0; i < resultTable.Columns.Count; i++)
63+
{
64+
csv.WriteField(row[i]);
65+
}
66+
csv.NextRecord();
67+
}
68+
}
69+
}
70+
}
71+
}

BitFaster.Caching.ThroughputAnalysis/MemoryCacheAdaptor.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ public MemoryCacheAdaptor(int capacity)
3131

3232
public ICollection<K> Keys => throw new NotImplementedException();
3333

34+
private static readonly MemoryCacheEntryOptions SizeOne = new MemoryCacheEntryOptions() { Size = 1 };
35+
3436
public void AddOrUpdate(K key, V value)
3537
{
36-
throw new NotImplementedException();
38+
exMemoryCache.Set(key, value, SizeOne);
3739
}
3840

3941
public void Clear()
@@ -48,7 +50,6 @@ public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
4850

4951
public V GetOrAdd(K key, Func<K, V> valueFactory)
5052
{
51-
5253
if (!exMemoryCache.TryGetValue(key, out object result))
5354
{
5455
using ICacheEntry entry = exMemoryCache.CreateEntry(key);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BitFaster.Caching.ThroughputAnalysis
8+
{
9+
public enum Mode
10+
{
11+
Read,
12+
ReadWrite,
13+
Evict,
14+
Update,
15+
}
16+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
namespace BitFaster.Caching.ThroughputAnalysis
11+
{
12+
public class ParallelBenchmark
13+
{
14+
public static TimeSpan Run(Action<int> action, int threads)
15+
{
16+
Task[] tasks = new Task[threads];
17+
ManualResetEventSlim mre = new ManualResetEventSlim();
18+
19+
Action<int> syncStart = taskId =>
20+
{
21+
mre.Wait();
22+
action(taskId);
23+
};
24+
25+
for (int i = 0; i < tasks.Length; i++)
26+
{
27+
int index = i;
28+
tasks[i] = Task.Factory.StartNew(() => syncStart(index), TaskCreationOptions.LongRunning);
29+
}
30+
31+
// try to mitigate spam from MemoryCache
32+
for (int i = 0; i < 3; i++)
33+
{
34+
GC.Collect();
35+
}
36+
37+
var sw = Stopwatch.StartNew();
38+
mre.Set();
39+
Task.WaitAll(tasks);
40+
return sw.Elapsed;
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)