Open
Description
I recently discovered StringDictionary. To me it is not clear what's the benefit of using it instead of Dictionary<string,string>. Also benchmarks reveal that it is slower comparing to Dictionary<string,string>. When I searched the internet for its purpose people said its coming from old times https://stackoverflow.com/questions/627716/stringdictionary-vs-dictionarystring-string. So I am suggestion to mark StringDictionary as obsolete and remove it in the future, telling people to use Dictionary<string,string> instead. And maybe doing the same with StringCollection? Please correct me if I am wrong and there is an important reason to use StringDictionary over Dictionary<string,string>.
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-4960X CPU 3.60GHz (Haswell), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=3.1.100
[Host] : .NET Core 3.1.0 (CoreCLR 4.700.19.56402, CoreFX 4.700.19.56404), X64 RyuJIT
Job-JPPKML : .NET Core 3.1.0 (CoreCLR 4.700.19.56402, CoreFX 4.700.19.56404), X64 RyuJIT
Runtime=.NET Core 3.1 InvocationCount=1 UnrollFactor=1
Add
Method | Mean | Error | StdDev | Median | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|
Dictionary_50 | 5.347 us | 0.1100 us | 0.2145 us | 5.300 us | - | - | - | 2.5 KB |
StringDictionary_50 | 7.447 us | 0.1526 us | 0.2977 us | 7.300 us | - | - | - | 2.5 KB |
Dictionary_50k | 4,659.986 us | 81.8376 us | 72.5469 us | 4,665.150 us | - | - | - | 3124.38 KB |
StringDictionary_50k | 6,759.100 us | 129.5854 us | 121.2143 us | 6,716.400 us | - | - | - | 3124.38 KB |
Add Benchmark
[CoreJob]
[MemoryDiagnoser]
[RPlotExporter]
public class DictionaryTest
{
private Dictionary<string, string> dict = new Dictionary<string, string>();
private StringDictionary stringDict = new StringDictionary();
[IterationCleanup]
public void Cleanup()
{
dict.Clear();
stringDict.Clear();
}
[Benchmark]
public bool Dictionary_50()
{
for (int i = 0; i < 50; i++)
{
dict.Add(i.ToString(), i.ToString());
}
return true;
}
[Benchmark]
public bool StringDictionary_50()
{
for (int i = 0; i < 50; i++)
{
stringDict.Add(i.ToString(), i.ToString());
}
return true;
}
[Benchmark]
public bool Dictionary_50k()
{
for (int i = 0; i < 50_000; i++)
{
dict.Add(i.ToString(), i.ToString());
}
return true;
}
[Benchmark]
public bool StringDictionary_50k()
{
for (int i = 0; i < 50_000; i++)
{
stringDict.Add(i.ToString(), i.ToString());
}
return true;
}
}
Contains
Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|
Dictionary_50 | 2.772 us | 0.0139 us | 0.0124 us | 0.1602 | - | - | 1.25 KB |
StringDictionary_50 | 3.211 us | 0.0096 us | 0.0075 us | 0.1602 | - | - | 1.25 KB |
Dictionary_50k | 3,219.860 us | 45.3422 us | 42.4131 us | 203.1250 | - | - | 1562.21 KB |
StringDictionary_50k | 5,157.772 us | 104.9752 us | 207.2108 us | 203.1250 | - | - | 1562.19 KB |
Contains Benchmark
[CoreJob]
[MemoryDiagnoser]
[RPlotExporter]
public class DictionaryTest
{
private Dictionary<string, string> dict = new Dictionary<string, string>();
private StringDictionary stringDict = new StringDictionary();
[GlobalSetup]
public void Setup()
{
for (int i = 0; i < 50_000; i++)
{
dict.Add(i.ToString(), i.ToString());
stringDict.Add(i.ToString(), i.ToString());
}
}
[Benchmark]
public bool Dictionary_50()
{
for (int i = 0; i < 50; i++)
{
var success = dict.ContainsKey(i.ToString());
}
return true;
}
[Benchmark]
public bool StringDictionary_50()
{
for (int i = 0; i < 50; i++)
{
var success = stringDict.ContainsKey(i.ToString());
}
return true;
}
[Benchmark]
public bool Dictionary_50k()
{
for (int i = 0; i < 50_000; i++)
{
var success = dict.ContainsKey(i.ToString());
}
return true;
}
[Benchmark]
public bool StringDictionary_50k()
{
for (int i = 0; i < 50_000; i++)
{
var success = stringDict.ContainsKey(i.ToString());
}
return true;
}
}