Skip to content

Commit

Permalink
add TryGetValue_False_FrozenDictionary benchmark (#3432)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsitnik authored Nov 29, 2023
1 parent 0ce3cc9 commit 21bc5c2
Showing 1 changed file with 37 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace System.Collections
[BenchmarkCategory(Categories.ThirdParty)]
public abstract class Perf_FrozenDictionary_String
{
protected string[] _array;
protected string[] _array, _notFound;
protected Dictionary<string, string> _dictionary;
protected ImmutableDictionary<string, string> _immutableDictionary;
protected FrozenDictionary<string, string> _frozenDictionary;
Expand Down Expand Up @@ -65,12 +65,27 @@ public bool TryGetValue_True_FrozenDictionary()
return result;
}

protected void EnsureRightStrategyIsUsed(string name)
[Benchmark]
[BenchmarkCategory(Categories.Libraries)]
public bool TryGetValue_False_FrozenDictionary()
{
bool result = default;
var collection = _frozenDictionary;
string[] notFound = _notFound;
for (int i = 0; i < notFound.Length; i++)
result ^= collection.TryGetValue(notFound[i], out _);
return result;
}

protected void Verify(string name)
{
if (!_frozenDictionary.GetType().Name.Contains(name))
{
// commented out until https://github.com/dotnet/runtime/pull/87988 gets propagated to installer
// throw new InvalidOperationException($"Either we are using wrong strategy ({_frozenDictionary.GetType().Name}), or the type has been renamed.");
throw new InvalidOperationException($"Either we are using wrong strategy ({_frozenDictionary.GetType().Name}), or the type has been renamed.");
}
else if (_array.Length != _notFound.Length || _array.Any(text => _notFound.Contains(text)))
{
throw new InvalidOperationException("Invalid state");
}
}
}
Expand All @@ -90,14 +105,16 @@ public override void Setup()
throw new ArgumentException($"{nameof(Count)} needs to be a multiply of {nameof(ItemsPerBucket)}");
}

_array = Enumerable.Range(1, Count / ItemsPerBucket)
string[] all = Enumerable.Range(1, Count * 2 / ItemsPerBucket)
.SelectMany(length => Enumerable.Range('a', ItemsPerBucket).Select(character => new string((char)character, length)))
.ToArray();
_array = all.Take(Count).ToArray();
_notFound = all.Skip(Count).ToArray();
_dictionary = _array.ToDictionary(item => item, item => item);
_immutableDictionary = _dictionary.ToImmutableDictionary();
_frozenDictionary = _dictionary.ToFrozenDictionary();

EnsureRightStrategyIsUsed("LengthBucketsFrozenDictionary");
Verify("LengthBucketsFrozenDictionary");
}
}

Expand All @@ -108,14 +125,16 @@ public class Perf_SingleCharFrozenDictionary : Perf_FrozenDictionary_String

public override void Setup()
{
_array = Enumerable.Range(char.MinValue, Count)
string[] all = Enumerable.Range(char.MinValue, Count * 2)
.Select(character => new string((char)character, 10))
.ToArray();
_array = all.Take(Count).ToArray();
_notFound = all.Skip(Count).ToArray();
_dictionary = _array.ToDictionary(item => item, item => item);
_immutableDictionary = _dictionary.ToImmutableDictionary();
_frozenDictionary = _dictionary.ToFrozenDictionary();

EnsureRightStrategyIsUsed("SingleChar");
Verify("SingleChar");
}
}

Expand All @@ -137,18 +156,20 @@ public override void Setup()
// bcbbbbbb
// bdbbbbbb
// so the first char is not unique, but the combination of 1st and 2nd is.
_array = Enumerable.Range(char.MinValue, Count / 2)
string[] all = Enumerable.Range(char.MinValue, Count)
.SelectMany(character => new string[]
{
$"{(char)character}{(char)(character+1)}{new string((char)character, 8)}",
$"{(char)character}{(char)(character+2)}{new string((char)character, 8)}"
})
.ToArray();
_array = all.Take(Count).ToArray();
_notFound = all.Skip(Count).ToArray();
_dictionary = _array.ToDictionary(item => item, item => item);
_immutableDictionary = _dictionary.ToImmutableDictionary();
_frozenDictionary = _dictionary.ToFrozenDictionary();

EnsureRightStrategyIsUsed("Substring");
Verify("Substring");
}
}

Expand All @@ -159,16 +180,17 @@ public class Perf_DefaultFrozenDictionary : Perf_FrozenDictionary_String

public override void Setup()
{
_array = Count == 10
string[] all = Count == 10
// to avoid using LengthBucketsFrozenDictionary we specify the same length for more than 5 strings
? ValuesGenerator.ArrayOfUniqueStrings(10, minLength: 25, maxLength: 25)
: ValuesGenerator.ArrayOfUniqueValues<string>(Count);

? ValuesGenerator.ArrayOfUniqueStrings(10 * 2, minLength: 25, maxLength: 25)
: ValuesGenerator.ArrayOfUniqueValues<string>(Count * 2);
_array = all.Take(Count).ToArray();
_notFound = all.Skip(Count).ToArray();
_dictionary = _array.ToDictionary(item => item, item => item);
_immutableDictionary = _dictionary.ToImmutableDictionary();
_frozenDictionary = _dictionary.ToFrozenDictionary();

EnsureRightStrategyIsUsed("OrdinalStringFrozenDictionary");
Verify("OrdinalStringFrozenDictionary");
}
}
}

0 comments on commit 21bc5c2

Please sign in to comment.