ModernUO/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs
Kamron Batman b0f8fe0350
fix: Optimize OrderedHashSet and introduce more high perf collections (#679)
* Optimizes OrderedHashSet using the learnings here: https://github.com/dotnet/runtime/issues/10050
* Removes ValueCollection since it was a relic from the conversion of the OrderedDictionary
* Centralizes throw strings.
* Adds pooled ordered hash set (but doesn't use it)

Closes #448
2021-08-08 21:37:25 -07:00

130 lines
3.3 KiB
C#

using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using Server.Collections;
namespace Benchmarks
{
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.NetCoreApp50)]
public class BenchmarkOrderedHashSet
{
private readonly string[] _iterations = new string[16];
[IterationSetup]
public void IterationSetup()
{
for (var i = 0; i < _iterations.Length; i++)
{
_iterations[i] = i.ToString();
}
}
[Benchmark]
public int UsingList()
{
var list = new List<string>();
for (int i = 0; i < _iterations.Length / 2; i++)
{
AddIfNotPresent(list, _iterations[i]);
}
for (int i = 0; i < _iterations.Length; i++)
{
AddIfNotPresent(list, _iterations[i]);
}
for (int i = 0; i < list.Count; i++)
{
list[i].ToString();
}
return list.Count;
}
private static int AddIfNotPresent<T>(List<T> list, T item)
{
var index = list.IndexOf(item);
if (index > -1)
{
return index;
}
list.Add(item);
return list.Count - 1;
}
[Benchmark]
public int UsingOrderedHashSet()
{
var ordered = new OrderedHashSet<string>();
for (int i = 0; i < _iterations.Length / 2; i++)
{
ordered.GetOrAdd(_iterations[i]).ToString();
}
for (int i = 0; i < _iterations.Length; i++)
{
ordered.GetOrAdd(_iterations[i]).ToString();
}
foreach (var str in ordered)
{
str.ToString();
}
return ordered.Count;
}
[Benchmark]
public int UsingPooledOrderedHashSet()
{
var ordered = new PooledOrderedHashSet<string>();
for (int i = 0; i < _iterations.Length / 2; i++)
{
ordered.GetOrAdd(_iterations[i]).ToString();
}
for (int i = 0; i < _iterations.Length; i++)
{
ordered.GetOrAdd(_iterations[i]).ToString();
}
foreach (var str in ordered)
{
str.ToString();
}
return ordered.Count;
}
[Benchmark]
public int UsingHashSet()
{
var hashSet = new HashSet<(string, int)>(new OrderedStringComparer());
for (int i = 0; i < _iterations.Length / 2; i++)
{
hashSet.Add((_iterations[i], i));
}
for (int i = 0; i < _iterations.Length; i++)
{
hashSet.Add((_iterations[i], i));
}
foreach (var str in hashSet)
{
str.ToString();
}
return hashSet.Count;
}
private class OrderedStringComparer : EqualityComparer<(string, int)>
{
public override bool Equals((string, int) x, (string, int) y) => x.Item1.Equals(y.Item1, System.StringComparison.Ordinal);
public override int GetHashCode((string, int) obj) => obj.Item1.GetHashCode();
}
}
}