Skip to content

Commit 16de12e

Browse files
Dictionary key by value: retarget net10.0, add prebuilt reverse map benchmarks (#2235)
Both projects move from net8.0 to net10.0. BenchmarkDotNet 0.15.8 and the test packages bumped to today's newest stable. The existing benchmark charges the two reversing methods a full build on every call, which measures a single lookup. ReverseDictionaryLookup builds a reverse Dictionary and a FrozenDictionary once, and two new benchmarks time only the TryGetValue against each, with the maps built in GlobalSetup. The four existing benchmarks are unchanged. Each new method gets the same pair of tests the existing four have.
1 parent 599d760 commit 16de12e

6 files changed

Lines changed: 93 additions & 7 deletions

File tree

‎collections-dictionary/GetDictionaryKeyByValue/GetDictionaryKeyByValue/DictionaryHelperBenchmark.cs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public class DictionaryHelperBenchmark
1313

1414
private readonly DictionaryHelper _dictionaryHelper = new(_benchmarkDict, "NonExistentValue");
1515

16+
private ReverseDictionaryLookup _reverseDictionaryLookup = null!;
17+
1618
private static Dictionary<string, string> GetDictionary()
1719
{
1820
var benchmarkDict = new Dictionary<string, string>(100000);
@@ -26,6 +28,10 @@ private static Dictionary<string, string> GetDictionary()
2628
return benchmarkDict;
2729
}
2830

31+
[GlobalSetup]
32+
public void Setup()
33+
=> _reverseDictionaryLookup = new(_benchmarkDict);
34+
2935
[Benchmark]
3036
public string? UseReverseDictionary()
3137
=> _dictionaryHelper.UseReverseDictionary();
@@ -41,4 +47,12 @@ private static Dictionary<string, string> GetDictionary()
4147
[Benchmark]
4248
public string? LoopThroughTheKeys()
4349
=> _dictionaryHelper.LoopThroughKeys();
50+
51+
[Benchmark]
52+
public string? UsePrebuiltReverseDictionary()
53+
=> _reverseDictionaryLookup.GetKeyFromReverseDictionary("NonExistentValue");
54+
55+
[Benchmark]
56+
public string? UsePrebuiltFrozenDictionary()
57+
=> _reverseDictionaryLookup.GetKeyFromFrozenReverseDictionary("NonExistentValue");
4458
}

‎collections-dictionary/GetDictionaryKeyByValue/GetDictionaryKeyByValue/GetDictionaryKeyByValue.csproj‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
11+
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
1212
</ItemGroup>
1313

1414
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Collections.Frozen;
2+
3+
namespace GetDictionaryKeyByValue;
4+
5+
public class ReverseDictionaryLookup(Dictionary<string, string> dict)
6+
{
7+
private readonly Dictionary<string, string> _reverseDict = BuildReverseDictionary(dict);
8+
9+
private readonly FrozenDictionary<string, string> _frozenReverseDict
10+
= BuildReverseDictionary(dict).ToFrozenDictionary();
11+
12+
public string? GetKeyFromReverseDictionary(string value)
13+
{
14+
_reverseDict.TryGetValue(value, out var key);
15+
16+
return key;
17+
}
18+
19+
public string? GetKeyFromFrozenReverseDictionary(string value)
20+
{
21+
_frozenReverseDict.TryGetValue(value, out var key);
22+
23+
return key;
24+
}
25+
26+
private static Dictionary<string, string> BuildReverseDictionary(Dictionary<string, string> dict)
27+
{
28+
var reverseDict = new Dictionary<string, string>(dict.Count);
29+
foreach (var keyValuePair in dict)
30+
{
31+
reverseDict.TryAdd(keyValuePair.Value, keyValuePair.Key);
32+
}
33+
34+
return reverseDict;
35+
}
36+
}

‎collections-dictionary/GetDictionaryKeyByValue/Tests/DictionaryHelperNullTest.cs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ private static readonly Dictionary<string, string> _dictionary
1616

1717
private readonly DictionaryHelper _dictionaryHelper = new(_dictionary, "NonExistentValue");
1818

19+
private readonly ReverseDictionaryLookup _reverseDictionaryLookup = new(_dictionary);
20+
1921
[Fact]
2022
public void GivenANonExistentValue_WhenUseReverseDictionaryIsCalled_ThenReturnsNull()
2123
{
@@ -47,4 +49,20 @@ public void GivenANonExistentValue_WhenLoopThroughKeysIsCalled_ThenReturnsNull()
4749

4850
Assert.Null(result);
4951
}
52+
53+
[Fact]
54+
public void GivenANonExistentValue_WhenGetKeyFromReverseDictionaryIsCalled_ThenReturnsNull()
55+
{
56+
var result = _reverseDictionaryLookup.GetKeyFromReverseDictionary("NonExistentValue");
57+
58+
Assert.Null(result);
59+
}
60+
61+
[Fact]
62+
public void GivenANonExistentValue_WhenGetKeyFromFrozenReverseDictionaryIsCalled_ThenReturnsNull()
63+
{
64+
var result = _reverseDictionaryLookup.GetKeyFromFrozenReverseDictionary("NonExistentValue");
65+
66+
Assert.Null(result);
67+
}
5068
}

‎collections-dictionary/GetDictionaryKeyByValue/Tests/DictionaryHelperPositiveTest.cs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ private static readonly Dictionary<string, string> _dictionary
1515

1616
private readonly DictionaryHelper _dictionaryHelper = new(_dictionary, "value3");
1717

18+
private readonly ReverseDictionaryLookup _reverseDictionaryLookup = new(_dictionary);
19+
1820
private static readonly string _expectedKey = "key3";
1921

2022
[Fact]
@@ -48,4 +50,20 @@ public void GivenAnExistentValue_WhenLoopThroughKeysIsCalled_ThenReturnsTheDesir
4850

4951
Assert.Equal(_expectedKey, result);
5052
}
53+
54+
[Fact]
55+
public void GivenAnExistentValue_WhenGetKeyFromReverseDictionaryIsCalled_ThenReturnsTheDesiredKey()
56+
{
57+
var result = _reverseDictionaryLookup.GetKeyFromReverseDictionary("value3");
58+
59+
Assert.Equal(_expectedKey, result);
60+
}
61+
62+
[Fact]
63+
public void GivenAnExistentValue_WhenGetKeyFromFrozenReverseDictionaryIsCalled_ThenReturnsTheDesiredKey()
64+
{
65+
var result = _reverseDictionaryLookup.GetKeyFromFrozenReverseDictionary("value3");
66+
67+
Assert.Equal(_expectedKey, result);
68+
}
5169
}

‎collections-dictionary/GetDictionaryKeyByValue/Tests/Tests.csproj‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77

@@ -10,10 +10,10 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="coverlet.collector" Version="6.0.0" />
14-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
15-
<PackageReference Include="xunit" Version="2.5.3" />
16-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
13+
<PackageReference Include="coverlet.collector" Version="10.0.1" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
15+
<PackageReference Include="xunit" Version="2.9.3" />
16+
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

0 commit comments

Comments
 (0)