Skip to content

Commit 56dd44b

Browse files
authored
Add more benchmarks. (#12)
1 parent 144fe86 commit 56dd44b

4 files changed

Lines changed: 122 additions & 1 deletion

File tree

Benchmark/Benchmark.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
<ItemGroup>
99
<PackageReference Include="BenchmarkDotNet" Version="0.11.4" />
10+
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.11.4" />
1011
</ItemGroup>
1112

1213
<ItemGroup>

Benchmark/HashCollisions.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using CacheTable;
2+
using System;
3+
using BenchmarkDotNet.Attributes;
4+
using System.Collections.Generic;
5+
using System.Collections.Concurrent;
6+
7+
namespace Benchmark
8+
{
9+
[CoreJob]
10+
[RPlotExporter, RankColumn]
11+
public class HashCollisions
12+
{
13+
private readonly CacheTable<WrappedInt, int> cacheTable = new CacheTable<WrappedInt, int>(10, 4);
14+
private readonly ConcurrentCacheTable<WrappedInt, int> concurrentCacheTable = new ConcurrentCacheTable<WrappedInt, int>(10, 4, Environment.ProcessorCount);
15+
private readonly Dictionary<WrappedInt, int> dictionary = new Dictionary<WrappedInt, int>();
16+
private readonly ConcurrentDictionary<WrappedInt, int> concurrentDictionary = new ConcurrentDictionary<WrappedInt, int>();
17+
18+
struct WrappedInt : IEquatable<WrappedInt>
19+
{
20+
public int Value;
21+
22+
public bool Equals(WrappedInt other) => this.Value == other.Value;
23+
24+
public override int GetHashCode() => 42;
25+
26+
public override bool Equals(object obj) => this.Equals((WrappedInt)obj);
27+
28+
public static implicit operator WrappedInt(int i) => new WrappedInt { Value = i };
29+
}
30+
31+
[Benchmark]
32+
public void CacheTable()
33+
{
34+
for (int i = 0; i < 4; i++) this.cacheTable[i] = i;
35+
}
36+
37+
[Benchmark]
38+
public void ConcurrentCacheTable()
39+
{
40+
for (int i = 0; i < 4; i++) this.concurrentCacheTable[i] = i;
41+
}
42+
43+
[Benchmark(Baseline = true)]
44+
public void Dictionary()
45+
{
46+
for (int i = 0; i < 4; i++) this.dictionary[i] = i;
47+
}
48+
49+
[Benchmark]
50+
public void ConcurrentDictionary()
51+
{
52+
for (int i = 0; i < 4; i++) this.concurrentDictionary[i] = i;
53+
}
54+
}
55+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Benchmark
88
{
99
[CoreJob]
1010
[RPlotExporter, RankColumn]
11-
public class SetSingleItem
11+
public class SetSingleInt
1212
{
1313
private readonly CacheTable<int, int> cacheTable = new CacheTable<int, int>(10, 4);
1414
private readonly ConcurrentCacheTable<int, int> concurrentCacheTable = new ConcurrentCacheTable<int, int>(10, 4, Environment.ProcessorCount);

Benchmark/SetSingleString.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using CacheTable;
2+
using System;
3+
using BenchmarkDotNet.Attributes;
4+
using System.Collections.Generic;
5+
using System.Collections.Concurrent;
6+
7+
namespace Benchmark
8+
{
9+
[CoreJob]
10+
[RPlotExporter, RankColumn]
11+
public class SetSingleString
12+
{
13+
private static readonly WrappedString Zero = "0";
14+
15+
private readonly CacheTable<WrappedString, int> cacheTable = new CacheTable<WrappedString, int>(10, 4);
16+
private readonly ConcurrentCacheTable<WrappedString, int> concurrentCacheTable = new ConcurrentCacheTable<WrappedString, int>(10, 4, Environment.ProcessorCount);
17+
private readonly Dictionary<WrappedString, int> dictionary = new Dictionary<WrappedString, int>();
18+
private readonly ConcurrentDictionary<WrappedString, int> concurrentDictionary = new ConcurrentDictionary<WrappedString, int>();
19+
20+
// Wrap the string because Dictionary has special code to optimize
21+
// string hashing. This levels the playing field.
22+
struct WrappedString : IEquatable<WrappedString>
23+
{
24+
public string Value;
25+
26+
public bool Equals(WrappedString other) => this.Value.Equals(other.Value);
27+
28+
public override int GetHashCode() => this.Value.GetHashCode();
29+
30+
public override bool Equals(object obj) => this.Equals((WrappedString)obj);
31+
32+
public static implicit operator WrappedString(string str) => new WrappedString { Value = str };
33+
}
34+
35+
[Benchmark]
36+
public void CacheTable()
37+
{
38+
this.cacheTable[Zero] = 0;
39+
}
40+
41+
[Benchmark]
42+
public void ConcurrentCacheTable()
43+
{
44+
this.concurrentCacheTable[Zero] = 0;
45+
}
46+
47+
[Benchmark]
48+
public void Dictionary()
49+
{
50+
this.dictionary[Zero] = 0;
51+
}
52+
53+
[Benchmark]
54+
public void ConcurrentDictionary()
55+
{
56+
this.concurrentDictionary[Zero] = 0;
57+
}
58+
59+
[Benchmark(Baseline = true)]
60+
public int Hash()
61+
{
62+
return Zero.GetHashCode();
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)