Skip to content

Instantly share code, notes, and snippets.

@nietras
Created April 1, 2020 16:33
Show Gist options
  • Save nietras/eb7bec7803e0e9c4e0e865a2e70ff254 to your computer and use it in GitHub Desktop.
Save nietras/eb7bec7803e0e9c4e0e865a2e70ff254 to your computer and use it in GitHub Desktop.
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.17763.1039 (1809/October2018Update/Redstone5)
Intel Core i7-8700 CPU 3.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=5.0.100-preview.1.20155.7
  [Host]     : .NET Core 3.1.2 (CoreCLR 4.700.20.6602, CoreFX 4.700.20.6702), X64 RyuJIT
  DefaultJob : .NET Core 3.1.2 (CoreCLR 4.700.20.6602, CoreFX 4.700.20.6702), X64 RyuJIT

Method Mean Error StdDev Ratio Gen 0 Gen 1 Gen 2 Allocated
OrderBy 1,316.0 ns 3.98 ns 3.73 ns 1.00 0.0992 - - 632 B
SortInPlaceMethodGroup 409.7 ns 0.98 ns 0.92 ns 0.31 0.0391 - - 248 B
SortInPlaceLambda 400.1 ns 0.93 ns 0.82 ns 0.30 0.0291 - - 184 B
IntroSortInPlaceLambda 339.5 ns 0.51 ns 0.45 ns 0.26 0.0238 - - 152 B
IntroSortInPlaceStruct 329.2 ns 1.00 ns 0.94 ns 0.25 0.0238 - - 152 B
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using BenchmarkDotNet.Attributes;
using DotNetCross.Sorting;
namespace DotNetCross.Sorting.Benchmarks
{
// https://github.com/KirillOsenkov/Benchmarks/blob/e9b3af701eb4bf98a598b866cc252349b50819e3/Benchmarks/Tests/SortDictionary.cs
[MemoryDiagnoser]
public class SortDictionary
{
private readonly Dictionary<string, string> dictionary = new Dictionary<string, string>
{
{ "DestinationSubPath", "ICSharpCode.Decompiler.dll" },
{ "NuGetPackageId", "ICSharpCode.Decompiler" },
{ "AssetType", "runtime" },
{ "PackageVersion", "5.0.2.5153" },
{ "PackageName", "ICSharpCode.Decompiler" },
{ "NuGetPackageVersion", "5.0.2.5153" },
{ "CopyLocal", "true" },
{ "PathInPackage", "lib/netstandard2.0/ICSharpCode.Decompiler.dll" },
};
[Benchmark(Baseline = true)]
public void OrderBy()
{
var result = dictionary.OrderBy(kvp => kvp.Key);
foreach (var item in result)
{
}
}
private int Comparer((string, string) left, (string, string) right)
{
return StringComparer.OrdinalIgnoreCase.Compare(left.Item1, right.Item1);
}
[Benchmark]
public void SortInPlaceMethodGroup()
{
var list = new List<(string key, string value)>(dictionary.Count);
foreach (var kvp in dictionary)
{
list.Add((kvp.Key, kvp.Value));
}
list.Sort(Comparer);
foreach (var kvp in list)
{
}
}
[Benchmark]
public void SortInPlaceLambda()
{
var list = new List<(string key, string value)>(dictionary.Count);
foreach (var kvp in dictionary)
{
list.Add((kvp.Key, kvp.Value));
}
list.Sort((l, r) => StringComparer.OrdinalIgnoreCase.Compare(l.key, r.key));
foreach (var kvp in list)
{
}
}
[Benchmark]
public void IntroSortInPlaceLambda()
{
Span<(string key, string value)> array = new (string key, string value)[dictionary.Count];
int i = 0;
foreach (var kvp in dictionary)
{
array[i] = (kvp.Key, kvp.Value);
++i;
}
// DotNetCross.Sorting preview :)
array.IntroSort((l, r) => StringComparer.OrdinalIgnoreCase.Compare(l.key, r.key));
foreach (var kvp in array)
{
}
}
[Benchmark]
public void IntroSortInPlaceStruct()
{
Span<(string key, string value)> array = new (string key, string value)[dictionary.Count];
int i = 0;
foreach (var kvp in dictionary)
{
array[i] = (kvp.Key, kvp.Value);
++i;
}
// DotNetCross.Sorting preview :)
array.IntroSort(new OrdinalComparer());
foreach (var kvp in array)
{
}
}
public readonly struct OrdinalComparer : IComparer<(string key, string value)>
{
public int Compare((string key, string value) x, (string key, string value) y) =>
string.Compare(x.key, y.key, StringComparison.OrdinalIgnoreCase);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment