Skip to content

Commit

Permalink
#35 first lookup benhmark
Browse files Browse the repository at this point in the history
  • Loading branch information
maximv committed Nov 7, 2020
1 parent 71aeaf7 commit 866d6eb
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 11 deletions.
56 changes: 47 additions & 9 deletions playground/ImTools.Benchmarks/ImHashMapBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -869,8 +869,27 @@ public class Lookup
| Dictionary_TryGetValue | 1000 | 19.170 ns | 0.0708 ns | 0.0628 ns | 1.67 | 0.01 | - | - | - | - |
| ConcurrentDictionary_TryGetValue | 1000 | 16.273 ns | 0.4046 ns | 0.5116 ns | 1.43 | 0.05 | - | - | - | - |
| ImmutableDict_TryGet | 1000 | 29.662 ns | 0.1529 ns | 0.1355 ns | 2.59 | 0.01 | - | - | - | - |
## V3 - baseline
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.572 (2004/?/20H1)
Intel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.403
[Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
DefaultJob : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
| Method | Count | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------------- |------ |----------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:|
| ImHashMap_TryFind | 1 | 7.569 ns | 0.2924 ns | 0.7117 ns | 1.00 | 0.00 | - | - | - | - |
| Experimental_ImHashMap_TryFind | 1 | 9.887 ns | 0.3380 ns | 0.7900 ns | 1.32 | 0.17 | - | - | - | - |
| ImHashMap234_TryFind | 1 | 8.864 ns | 0.3180 ns | 0.7557 ns | 1.18 | 0.16 | - | - | - | - |
| | | | | | | | | | | |
| ImHashMap_TryFind | 10 | 10.840 ns | 0.3560 ns | 0.8866 ns | 1.00 | 0.00 | - | - | - | - |
| Experimental_ImHashMap_TryFind | 10 | 15.429 ns | 0.3848 ns | 0.3214 ns | 1.41 | 0.13 | - | - | - | - |
| ImHashMap234_TryFind | 10 | 12.232 ns | 0.3887 ns | 0.9894 ns | 1.13 | 0.14 | - | - | - | - |
*/
[Params(1, 10, 100, 1_000)]// the 1000 does not add anything as the LookupKey stored higher in the tree, 1000)]
[Params(1, 10)]//, 100, 1_000)]// the 1000 does not add anything as the LookupKey stored higher in the tree, 1000)]
public int Count;

[GlobalSetup]
Expand All @@ -880,6 +899,8 @@ public void Populate()
_mapSlots = ImHashMapSlots_AddOrUpdate();
_mapV1 = AddOrUpdate_v1();
_mapExp = Experimental_ImHashMap_AddOrUpdate();
_map234 = ImHashMap234_AddOrUpdate();
_mapExp = Experimental_ImHashMap_AddOrUpdate();
_mapSlotsExp32 = Experimental_ImHashMapSlots32_AddOrUpdate();
_mapSlotsExp64 = Experimental_ImHashMapSlots64_AddOrUpdate();
_dict = Dict();
Expand Down Expand Up @@ -938,9 +959,19 @@ public ImTools.OldVersions.V1.ImHashMap<Type, string> AddOrUpdate_v1()

return map.AddOrUpdate(typeof(ImHashMapBenchmarks).GetHashCode(), typeof(ImHashMapBenchmarks), "!");
}

private ImTools.Experimental.ImMap<ImMap.KValue<Type>> _mapExp;

public ImTools.Experimental.ImHashMap234<Type, string> ImHashMap234_AddOrUpdate()
{
var map = ImTools.Experimental.ImHashMap234<Type, string>.Empty;

foreach (var key in _keys.Take(Count))
map = map.AddOrUpdate(key.GetHashCode(), key, "a");

return map.AddOrUpdate(typeof(ImHashMapBenchmarks).GetHashCode(), typeof(ImHashMapBenchmarks), "!");
}
private ImTools.Experimental.ImHashMap234<Type, string> _map234;

public ImTools.Experimental.ImMap<ImMap.KValue<Type>>[] Experimental_ImHashMapSlots32_AddOrUpdate()
{
var map = ImTools.Experimental.ImMapSlots.CreateWithEmpty<ImMap.KValue<Type>>();
Expand Down Expand Up @@ -1030,15 +1061,15 @@ public string ImHashMap_TryFind()
return result;
}

[Benchmark]
// [Benchmark]
public string ImHashMapSlots32_TryFind()
{
var hash = LookupKey.GetHashCode();
_mapSlots[hash & ImHashMapSlots.HASH_MASK_TO_FIND_SLOT].TryFind(hash, LookupKey, out var result);
return result;
}

[Benchmark]
// [Benchmark]
public string ImHashMap_TryFind_V1()
{
_mapV1.TryFind(LookupKey, out var result);
Expand All @@ -1053,43 +1084,50 @@ public string Experimental_ImHashMap_TryFind()
}

[Benchmark]
public string ImHashMap234_TryFind()
{
_map234.TryFind(LookupKey.GetHashCode(), LookupKey, out var result);
return (string)result;
}

// [Benchmark]
public string Experimental_ImHashMapSlots32_TryFind()
{
var hash = LookupKey.GetHashCode();
_mapSlotsExp32[hash & ImHashMapSlots.HASH_MASK_TO_FIND_SLOT].TryFind(hash, LookupKey, out var result);
return (string)result;
}

[Benchmark]
// [Benchmark]
public string Experimental_ImHashMapSlots64_TryFind()
{
var hash = LookupKey.GetHashCode();
_mapSlotsExp64[hash & 63].TryFind(hash, LookupKey, out var result);
return (string)result;
}

[Benchmark]
// [Benchmark]
public string DictionarySlim_TryGetValue()
{
_dictSlim.TryGetValue(LookupKey, out var result);
return result;
}

[Benchmark]
// [Benchmark]
public string Dictionary_TryGetValue()
{
_dict.TryGetValue(LookupKey, out var result);
return result;
}

[Benchmark]
// [Benchmark]
public string ConcurrentDictionary_TryGetValue()
{
_concurrentDict.TryGetValue(LookupKey, out var result);
return result;
}

[Benchmark]
// [Benchmark]
public string ImmutableDict_TryGet()
{
_immutableDict.TryGetValue(LookupKey, out var result);
Expand Down
4 changes: 2 additions & 2 deletions playground/ImTools.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ static void Main()
//BenchmarkRunner.Run<ImMapBenchmarks.LookupMissing>();
//BenchmarkRunner.Run<ImMapBenchmarks.Enumerate>();

BenchmarkRunner.Run<ImHashMapBenchmarks.Populate>();
//BenchmarkRunner.Run<ImHashMapBenchmarks.Lookup>();
// BenchmarkRunner.Run<ImHashMapBenchmarks.Populate>();
BenchmarkRunner.Run<ImHashMapBenchmarks.Lookup>();
//BenchmarkRunner.Run<ImHashMapBenchmarks.Enumerate>();

//BenchmarkRunner.Run<ImHashMapBenchmarks_StringString.Populate>();
Expand Down
32 changes: 32 additions & 0 deletions src/ImTools/ImTools.Experimental.234.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,38 @@ public static V GetValueOrDefault<K, V>(this ImHashMap234<K, V> map, int hash, K
public static V GetValueOrDefault<K, V>(this ImHashMap234<K, V> map, K key) =>
map.GetValueOrDefault(key.GetHashCode(), key);

/// <summary>Looks up for the key using its hash code and returns the `true` and the found value or `false`</summary>
[MethodImpl((MethodImplOptions)256)]
public static bool TryFind<K, V>(this ImHashMap234<K, V> map, int hash, K key, out V value)
{
var e = map.GetEntryOrDefault(hash);
if (e is ImHashMap234<K, V>.ValueEntry v)
{
if (e.Key.Equals(key))
{
value = v.Value;
return true;
}
}
else if (e is ImHashMap234<K, V>.ConflictsEntry c)
{
foreach (var x in c.Conflicts)
if (x.Key.Equals(key))
{
value = x.Value;
return true;
}
}

value = default(V);
return false;
}

/// <summary>Looks up for the key using its hash code and returns the `true` and the found value or `false`</summary>
[MethodImpl((MethodImplOptions)256)]
public static bool TryFind<K, V>(this ImHashMap234<K, V> map, K key, out V value) =>
map.TryFind(key.GetHashCode(), key, out value);

/// <summary>Adds or updates the value by key in the map, always returning the modified map.</summary>
[MethodImpl((MethodImplOptions)256)]
public static ImHashMap234<K, V> AddOrUpdate<K, V>(this ImHashMap234<K, V> map, int hash, K key, V value) =>
Expand Down

0 comments on commit 866d6eb

Please sign in to comment.