Skip to content

Commit

Permalink
fixed position optimized implementation's hashing; bumped to 4.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
protobufel committed May 31, 2017
1 parent 2c841da commit e7500e1
Show file tree
Hide file tree
Showing 24 changed files with 94 additions and 246 deletions.
8 changes: 4 additions & 4 deletions MultiKeyMap/MultiKeyMap.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
<RepositoryUrl>https://github.com/protobufel/multikeymapcsharp</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>c# library multikey dictionary</PackageTags>
<PackageReleaseNotes>improved benchmarks</PackageReleaseNotes>
<PackageReleaseNotes>fixed the position optimized implementation's hashing</PackageReleaseNotes>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<SignAssembly>False</SignAssembly>
<AssemblyVersion>4.0.20.0</AssemblyVersion>
<FileVersion>4.0.20.0</FileVersion>
<Version>4.0.20</Version>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<FileVersion>4.1.0.0</FileVersion>
<Version>4.1.0</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down
21 changes: 12 additions & 9 deletions MultiKeyMap/PositionMask/KeyMasks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal interface IKeyMask<T, K> : IEquatable<IKeyMask<T, K>>, IEquatable<K>, I
K Key { get; }
}

internal interface ISubKeyMask<T> : IEquatable<ISubKeyMask<T>>, IEquatable<T>
internal interface ISubKeyMask<T> : IEquatable<ISubKeyMask<T>>
{
T SubKey { get; }
int Position { get; }
Expand Down Expand Up @@ -82,6 +82,7 @@ IEnumerator IEnumerable.GetEnumerator()
internal class SubKeyMask<T> : ISubKeyMask<T>
{
public const int NonPositional = -1;
public const int NonPositionalHashCode = int.MaxValue >> 16;

public SubKeyMask(T subKey) : this(subKey, NonPositional)
{
Expand All @@ -98,14 +99,16 @@ public SubKeyMask(T subKey, int position)

public int Position { get; }

bool IEquatable<T>.Equals(T other)
{
return (other == null) ? false : SubKey.Equals(other);
}

public override int GetHashCode()
{
return SubKey.GetHashCode();
int hash = 13;

unchecked
{
hash = (hash + ((Position == NonPositional) ? NonPositionalHashCode : Position.GetHashCode())) * 47 + SubKey.GetHashCode();
}

return hash;
}

public bool Equals(ISubKeyMask<T> other)
Expand All @@ -125,7 +128,7 @@ public bool Equals(ISubKeyMask<T> other)
return false;
}

return SubKey.Equals(other.SubKey);
return Equals(SubKey, other.SubKey) && (Position == other.Position);
}

public override bool Equals(object obj)
Expand Down Expand Up @@ -186,7 +189,7 @@ public override bool Equals(ISubKeyMask<T> x, ISubKeyMask<T> y)

public override int GetHashCode(ISubKeyMask<T> obj)
{
return obj?.SubKey?.GetHashCode() ?? 0;
return obj?.GetHashCode() ?? 0;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ dotnet cli version=1.0.4


```
| Method | Strategy | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Allocated |
|---------------- |-------------------------------- |-----------:|----------:|----------:|-------:|---------:|--------:|-------:|----------:|
| **MultiKeyMap_Add** | **OptimizedForNonPositionalSearch** | **213.237 us** | **1.2228 us** | **1.0840 us** | **44.77** | **0.35** | **34.1797** | **0.2441** | **140.52 KB** |
| Dictionary_Add | OptimizedForNonPositionalSearch | 4.764 us | 0.0344 us | 0.0305 us | 1.00 | 0.00 | 2.4872 | - | 10.21 KB |
| **MultiKeyMap_Add** | **OptimizedForPositionalSearch** | **310.649 us** | **0.4653 us** | **0.3364 us** | **64.90** | **0.22** | **50.7813** | **-** | **208.48 KB** |
| Dictionary_Add | OptimizedForPositionalSearch | 4.787 us | 0.0207 us | 0.0162 us | 1.00 | 0.00 | 2.5177 | - | 10.32 KB |
| Method | Strategy | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Allocated |
|---------------- |-------------------------------- |-----------:|----------:|----------:|-------:|---------:|--------:|--------:|----------:|
| **MultiKeyMap_Add** | **OptimizedForNonPositionalSearch** | **214.843 us** | **1.7234 us** | **1.6121 us** | **44.18** | **0.38** | **34.1797** | **0.2441** | **140.52 KB** |
| Dictionary_Add | OptimizedForNonPositionalSearch | 4.864 us | 0.0273 us | 0.0242 us | 1.00 | 0.00 | 2.4872 | - | 10.21 KB |
| **MultiKeyMap_Add** | **OptimizedForPositionalSearch** | **403.821 us** | **2.1189 us** | **1.8784 us** | **82.24** | **0.58** | **67.2852** | **33.6263** | **388.84 KB** |
| Dictionary_Add | OptimizedForPositionalSearch | 4.911 us | 0.0314 us | 0.0279 us | 1.00 | 0.00 | 2.5177 | - | 10.32 KB |
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,RemoveOutliers,Affinity,Jit,Platform,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,RetainVm,Server,Clock,EngineFactory,Toolchain,InvocationCount,IterationTime,LaunchCount,RunStrategy,TargetCount,UnrollFactor,WarmupCount,Strategy,Mean,Error,StdDev,Scaled,ScaledSD,Gen 0,Gen 1,Allocated
MultiKeyMap_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,213.237 us,1.2228 us,1.0840 us,44.77,0.35,34.1797,0.2441,140.52 KB
Dictionary_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,4.764 us,0.0344 us,0.0305 us,1.00,0.00,2.4872,-,10.21 KB
MultiKeyMap_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,310.649 us,0.4653 us,0.3364 us,64.90,0.22,50.7813,-,208.48 KB
Dictionary_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,4.787 us,0.0207 us,0.0162 us,1.00,0.00,2.5177,-,10.32 KB
MultiKeyMap_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,214.843 us,1.7234 us,1.6121 us,44.18,0.38,34.1797,0.2441,140.52 KB
Dictionary_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,4.864 us,0.0273 us,0.0242 us,1.00,0.00,2.4872,-,10.21 KB
MultiKeyMap_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,403.821 us,2.1189 us,1.8784 us,82.24,0.58,67.2852,33.6263,388.84 KB
Dictionary_Add,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,4.911 us,0.0314 us,0.0279 us,1.00,0.00,2.5177,-,10.32 KB
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
<table>
<thead><tr><th> Method</th><th> Strategy</th><th>Mean</th><th>Error</th><th>StdDev</th><th>Scaled</th><th>ScaledSD</th><th>Gen 0</th><th>Gen 1</th><th>Allocated</th>
</tr>
</thead><tbody><tr><td>MultiKeyMap_Add</td><td>OptimizedForNonPositionalSearch</td><td>213.237 us</td><td>1.2228 us</td><td>1.0840 us</td><td>44.77</td><td>0.35</td><td>34.1797</td><td>0.2441</td><td>140.52 KB</td>
</tr><tr><td>Dictionary_Add</td><td>OptimizedForNonPositionalSearch</td><td>4.764 us</td><td>0.0344 us</td><td>0.0305 us</td><td>1.00</td><td>0.00</td><td>2.4872</td><td>-</td><td>10.21 KB</td>
</tr><tr><td>MultiKeyMap_Add</td><td>OptimizedForPositionalSearch</td><td>310.649 us</td><td>0.4653 us</td><td>0.3364 us</td><td>64.90</td><td>0.22</td><td>50.7813</td><td>-</td><td>208.48 KB</td>
</tr><tr><td>Dictionary_Add</td><td>OptimizedForPositionalSearch</td><td>4.787 us</td><td>0.0207 us</td><td>0.0162 us</td><td>1.00</td><td>0.00</td><td>2.5177</td><td>-</td><td>10.32 KB</td>
</thead><tbody><tr><td>MultiKeyMap_Add</td><td>OptimizedForNonPositionalSearch</td><td>214.843 us</td><td>1.7234 us</td><td>1.6121 us</td><td>44.18</td><td>0.38</td><td>34.1797</td><td>0.2441</td><td>140.52 KB</td>
</tr><tr><td>Dictionary_Add</td><td>OptimizedForNonPositionalSearch</td><td>4.864 us</td><td>0.0273 us</td><td>0.0242 us</td><td>1.00</td><td>0.00</td><td>2.4872</td><td>-</td><td>10.21 KB</td>
</tr><tr><td>MultiKeyMap_Add</td><td>OptimizedForPositionalSearch</td><td>403.821 us</td><td>2.1189 us</td><td>1.8784 us</td><td>82.24</td><td>0.58</td><td>67.2852</td><td>33.6263</td><td>388.84 KB</td>
</tr><tr><td>Dictionary_Add</td><td>OptimizedForPositionalSearch</td><td>4.911 us</td><td>0.0314 us</td><td>0.0279 us</td><td>1.00</td><td>0.00</td><td>2.5177</td><td>-</td><td>10.32 KB</td>
</tr></tbody></table>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dotnet cli version=1.0.4
```
| Method | Strategy | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated |
|---------------------------- |-------------------------------- |----------:|----------:|----------:|-------:|---------:|-------:|----------:|
| **CreateDictionaryMultiKeyMap** | **OptimizedForNonPositionalSearch** | **161.13 ns** | **0.6697 ns** | **0.5936 ns** | **9.55** | **0.08** | **0.0627** | **264 B** |
| CreateDictionary | OptimizedForNonPositionalSearch | 16.88 ns | 0.1433 ns | 0.1270 ns | 1.00 | 0.00 | 0.0190 | 80 B |
| **CreateDictionaryMultiKeyMap** | **OptimizedForPositionalSearch** | **204.40 ns** | **1.6882 ns** | **1.4965 ns** | **11.88** | **0.13** | **0.0894** | **376 B** |
| CreateDictionary | OptimizedForPositionalSearch | 17.21 ns | 0.1508 ns | 0.1410 ns | 1.00 | 0.00 | 0.0190 | 80 B |
| **CreateDictionaryMultiKeyMap** | **OptimizedForNonPositionalSearch** | **168.54 ns** | **1.1452 ns** | **1.0713 ns** | **9.74** | **0.09** | **0.0627** | **264 B** |
| CreateDictionary | OptimizedForNonPositionalSearch | 17.30 ns | 0.1213 ns | 0.1134 ns | 1.00 | 0.00 | 0.0190 | 80 B |
| **CreateDictionaryMultiKeyMap** | **OptimizedForPositionalSearch** | **210.38 ns** | **0.9357 ns** | **0.7814 ns** | **12.27** | **0.09** | **0.0894** | **376 B** |
| CreateDictionary | OptimizedForPositionalSearch | 17.15 ns | 0.1261 ns | 0.1118 ns | 1.00 | 0.00 | 0.0190 | 80 B |
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,RemoveOutliers,Affinity,Jit,Platform,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,RetainVm,Server,Clock,EngineFactory,Toolchain,InvocationCount,IterationTime,LaunchCount,RunStrategy,TargetCount,UnrollFactor,WarmupCount,Strategy,Mean,Error,StdDev,Scaled,ScaledSD,Gen 0,Allocated
CreateDictionaryMultiKeyMap,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,161.13 ns,0.6697 ns,0.5936 ns,9.55,0.08,0.0627,264 B
CreateDictionary,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,16.88 ns,0.1433 ns,0.1270 ns,1.00,0.00,0.0190,80 B
CreateDictionaryMultiKeyMap,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,204.40 ns,1.6882 ns,1.4965 ns,11.88,0.13,0.0894,376 B
CreateDictionary,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,17.21 ns,0.1508 ns,0.1410 ns,1.00,0.00,0.0190,80 B
CreateDictionaryMultiKeyMap,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,168.54 ns,1.1452 ns,1.0713 ns,9.74,0.09,0.0627,264 B
CreateDictionary,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForNonPositionalSearch,17.30 ns,0.1213 ns,0.1134 ns,1.00,0.00,0.0190,80 B
CreateDictionaryMultiKeyMap,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,210.38 ns,0.9357 ns,0.7814 ns,12.27,0.09,0.0894,376 B
CreateDictionary,Default,False,Default,Default,Default,Default,Default,Default,255,RyuJit,X64,Core,False,True,False,True,False,False,Default,Default,Default,1,Default,Default,Default,Default,16,Default,OptimizedForPositionalSearch,17.15 ns,0.1261 ns,0.1118 ns,1.00,0.00,0.0190,80 B
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
<table>
<thead><tr><th> Method</th><th> Strategy</th><th>Mean</th><th>Error</th><th>StdDev</th><th>Scaled</th><th>ScaledSD</th><th>Gen 0</th><th>Allocated</th>
</tr>
</thead><tbody><tr><td>CreateDictionaryMultiKeyMap</td><td>OptimizedForNonPositionalSearch</td><td>161.13 ns</td><td>0.6697 ns</td><td>0.5936 ns</td><td>9.55</td><td>0.08</td><td>0.0627</td><td>264 B</td>
</tr><tr><td> CreateDictionary</td><td>OptimizedForNonPositionalSearch</td><td>16.88 ns</td><td>0.1433 ns</td><td>0.1270 ns</td><td>1.00</td><td>0.00</td><td>0.0190</td><td>80 B</td>
</tr><tr><td>CreateDictionaryMultiKeyMap</td><td>OptimizedForPositionalSearch</td><td>204.40 ns</td><td>1.6882 ns</td><td>1.4965 ns</td><td>11.88</td><td>0.13</td><td>0.0894</td><td>376 B</td>
</tr><tr><td> CreateDictionary</td><td>OptimizedForPositionalSearch</td><td>17.21 ns</td><td>0.1508 ns</td><td>0.1410 ns</td><td>1.00</td><td>0.00</td><td>0.0190</td><td>80 B</td>
</thead><tbody><tr><td>CreateDictionaryMultiKeyMap</td><td>OptimizedForNonPositionalSearch</td><td>168.54 ns</td><td>1.1452 ns</td><td>1.0713 ns</td><td>9.74</td><td>0.09</td><td>0.0627</td><td>264 B</td>
</tr><tr><td> CreateDictionary</td><td>OptimizedForNonPositionalSearch</td><td>17.30 ns</td><td>0.1213 ns</td><td>0.1134 ns</td><td>1.00</td><td>0.00</td><td>0.0190</td><td>80 B</td>
</tr><tr><td>CreateDictionaryMultiKeyMap</td><td>OptimizedForPositionalSearch</td><td>210.38 ns</td><td>0.9357 ns</td><td>0.7814 ns</td><td>12.27</td><td>0.09</td><td>0.0894</td><td>376 B</td>
</tr><tr><td> CreateDictionary</td><td>OptimizedForPositionalSearch</td><td>17.15 ns</td><td>0.1261 ns</td><td>0.1118 ns</td><td>1.00</td><td>0.00</td><td>0.0190</td><td>80 B</td>
</tr></tbody></table>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ dotnet cli version=1.0.4


```
| Method | Strategy | Mean | Error | StdDev | Scaled | Gen 0 | Gen 1 | Allocated |
|------------------- |-------------------------------- |---------:|----------:|----------:|-------:|--------:|-------:|----------:|
| **MultiKeyMap_Remove** | **OptimizedForNonPositionalSearch** | **603.8 us** | **3.5025 us** | **3.1049 us** | **2.75** | **68.3594** | **-** | **283.21 KB** |
| Dictionary_Remove | OptimizedForNonPositionalSearch | 219.7 us | 0.4560 us | 0.3808 us | 1.00 | 36.6211 | - | 150.4 KB |
| **MultiKeyMap_Remove** | **OptimizedForPositionalSearch** | **727.5 us** | **2.3995 us** | **2.0037 us** | **2.31** | **96.6797** | **0.9766** | **398.04 KB** |
| Dictionary_Remove | OptimizedForPositionalSearch | 315.0 us | 2.0312 us | 1.8006 us | 1.00 | 53.2227 | 0.4883 | 218.35 KB |
| Method | Strategy | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Allocated |
|------------------- |-------------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|--------:|----------:|
| **MultiKeyMap_Remove** | **OptimizedForNonPositionalSearch** | **628.8 us** | **4.9192 us** | **4.3607 us** | **2.80** | **0.02** | **68.3594** | **-** | **283.21 KB** |
| Dictionary_Remove | OptimizedForNonPositionalSearch | 224.7 us | 0.9011 us | 0.7988 us | 1.00 | 0.00 | 36.6211 | - | 150.4 KB |
| **MultiKeyMap_Remove** | **OptimizedForPositionalSearch** | **839.4 us** | **4.4798 us** | **4.1904 us** | **2.10** | **0.01** | **126.6927** | **31.7708** | **578.41 KB** |
| Dictionary_Remove | OptimizedForPositionalSearch | 400.2 us | 2.0390 us | 1.9073 us | 1.00 | 0.00 | 83.0078 | 27.3438 | 398.72 KB |
Loading

0 comments on commit e7500e1

Please sign in to comment.