Skip to content

Instantly share code, notes, and snippets.

@nyctef
Created February 17, 2021 16:35
Show Gist options
  • Save nyctef/1bbaa9e2cc41bb5ec21a07434c23c02e to your computer and use it in GitHub Desktop.
Save nyctef/1bbaa9e2cc41bb5ec21a07434c23c02e to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet;
using BenchmarkDotNet.Attributes;
namespace dictionary_vs_array
{
public class Benchmarks
{
[Params(1, 3, 5, 10, 20, 50, 100)]
public int NumItems { get; set; }
[Params(1, 1000)]
public int StringLength { get; set; }
private string[] arrayData;
private Dictionary<string, string> dictionaryData;
[GlobalSetup]
public void GlobalSetup()
{
arrayData = new string[NumItems];
dictionaryData = new Dictionary<string, string>(NumItems);
for (int i = 0; i < NumItems; i++)
{
var value = new string((char)('a' + i), StringLength);
arrayData[i] = value;
dictionaryData[value] = null;
}
}
[Benchmark]
public bool ArrayLinearSearch()
{
var result = true;
for (int i = 0; i < NumItems; i++)
{
result &= Array.IndexOf(arrayData, arrayData[i]) >= 0;
}
return result;
}
[Benchmark]
public bool DictionaryLookup()
{
var result = true;
for (int i = 0; i < NumItems; i++)
{
result &= dictionaryData.ContainsKey(arrayData[i]);
}
return result;
}
}
}
// * Summary *
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19042
AMD Ryzen 9 3900XT, 1 CPU, 24 logical and 12 physical cores
.NET Core SDK=5.0.102
[Host] : .NET Core 3.1.11 (CoreCLR 4.700.20.56602, CoreFX 4.700.20.56604), X64 RyuJIT
DefaultJob : .NET Core 3.1.11 (CoreCLR 4.700.20.56602, CoreFX 4.700.20.56604), X64 RyuJIT
| Method | NumItems | StringLength | Mean | Error | StdDev |
|------------------ |--------- |------------- |-------------:|-----------:|-----------:|
| ArrayLinearSearch | 1 | 1 | 12.11 ns | 0.072 ns | 0.060 ns |
| DictionaryLookup | 1 | 1 | 12.86 ns | 0.245 ns | 0.229 ns |
| ArrayLinearSearch | 1 | 1000 | 11.75 ns | 0.046 ns | 0.043 ns |
| DictionaryLookup | 1 | 1000 | 209.88 ns | 0.333 ns | 0.278 ns |
| ArrayLinearSearch | 3 | 1 | 47.07 ns | 0.267 ns | 0.249 ns |
| DictionaryLookup | 3 | 1 | 37.14 ns | 0.245 ns | 0.218 ns |
| ArrayLinearSearch | 3 | 1000 | 45.75 ns | 0.472 ns | 0.442 ns |
| DictionaryLookup | 3 | 1000 | 655.17 ns | 3.568 ns | 3.337 ns |
| ArrayLinearSearch | 5 | 1 | 107.64 ns | 0.625 ns | 0.585 ns |
| DictionaryLookup | 5 | 1 | 61.30 ns | 0.406 ns | 0.380 ns |
| ArrayLinearSearch | 5 | 1000 | 105.98 ns | 1.803 ns | 1.687 ns |
| DictionaryLookup | 5 | 1000 | 1,073.08 ns | 3.237 ns | 2.527 ns |
| ArrayLinearSearch | 10 | 1 | 362.17 ns | 2.359 ns | 1.970 ns |
| DictionaryLookup | 10 | 1 | 121.88 ns | 1.280 ns | 1.198 ns |
| ArrayLinearSearch | 10 | 1000 | 353.33 ns | 3.352 ns | 3.135 ns |
| DictionaryLookup | 10 | 1000 | 2,234.56 ns | 8.399 ns | 7.445 ns |
| ArrayLinearSearch | 20 | 1 | 1,269.12 ns | 24.956 ns | 39.583 ns |
| DictionaryLookup | 20 | 1 | 276.19 ns | 1.474 ns | 1.379 ns |
| ArrayLinearSearch | 20 | 1000 | 1,152.46 ns | 9.778 ns | 8.668 ns |
| DictionaryLookup | 20 | 1000 | 4,387.22 ns | 31.847 ns | 29.789 ns |
| ArrayLinearSearch | 50 | 1 | 6,599.39 ns | 108.039 ns | 95.774 ns |
| DictionaryLookup | 50 | 1 | 761.05 ns | 2.331 ns | 2.067 ns |
| ArrayLinearSearch | 50 | 1000 | 6,257.57 ns | 64.792 ns | 60.606 ns |
| DictionaryLookup | 50 | 1000 | 11,029.63 ns | 108.646 ns | 101.627 ns |
| ArrayLinearSearch | 100 | 1 | 25,399.07 ns | 460.248 ns | 430.516 ns |
| DictionaryLookup | 100 | 1 | 1,282.42 ns | 16.019 ns | 14.984 ns |
| ArrayLinearSearch | 100 | 1000 | 22,699.34 ns | 142.476 ns | 133.272 ns |
| DictionaryLookup | 100 | 1000 | 22,072.53 ns | 160.632 ns | 150.255 ns |
// * Hints *
Outliers
Benchmarks.ArrayLinearSearch: Default -> 2 outliers were removed (13.89 ns, 14.01 ns)
Benchmarks.DictionaryLookup: Default -> 2 outliers were removed (212.30 ns, 213.99 ns)
Benchmarks.ArrayLinearSearch: Default -> 1 outlier was detected (48.05 ns)
Benchmarks.DictionaryLookup: Default -> 1 outlier was removed (57.55 ns)
Benchmarks.DictionaryLookup: Default -> 3 outliers were removed (1.08 us..1.09 us)
Benchmarks.ArrayLinearSearch: Default -> 2 outliers were removed (372.92 ns, 373.19 ns)
Benchmarks.DictionaryLookup: Default -> 1 outlier was removed (2.27 us)
Benchmarks.ArrayLinearSearch: Default -> 1 outlier was removed (1.43 us)
Benchmarks.ArrayLinearSearch: Default -> 1 outlier was removed (1.19 us)
Benchmarks.ArrayLinearSearch: Default -> 1 outlier was removed (6.84 us)
Benchmarks.DictionaryLookup: Default -> 1 outlier was removed (770.79 ns)
Benchmarks.ArrayLinearSearch: Default -> 1 outlier was detected (22.40 us)
// * Legends *
NumItems : Value of the 'NumItems' parameter
StringLength : Value of the 'StringLength' parameter
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
1 ns : 1 Nanosecond (0.000000001 sec)
// ***** BenchmarkRunner: End *****
// ** Remained 0 benchmark(s) to run **
Run time: 00:09:06 (546.59 sec), executed benchmarks: 28
Global total time: 00:09:10 (550.02 sec), executed benchmarks: 28
using BenchmarkDotNet.Running;
namespace dictionary_vs_array
{
public class Program
{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Benchmarks>();
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<Configuration>Release</Configuration>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.12.0"/>
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment