diff --git a/src/benchmarks/micro/libraries/System.Collections/Frozen/Perf_FrozenDictionary_String.cs b/src/benchmarks/micro/libraries/System.Collections/Frozen/Perf_FrozenDictionary_String.cs index 137792b2197..76cd74096f4 100644 --- a/src/benchmarks/micro/libraries/System.Collections/Frozen/Perf_FrozenDictionary_String.cs +++ b/src/benchmarks/micro/libraries/System.Collections/Frozen/Perf_FrozenDictionary_String.cs @@ -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 _dictionary; protected ImmutableDictionary _immutableDictionary; protected FrozenDictionary _frozenDictionary; @@ -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"); } } } @@ -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"); } } @@ -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"); } } @@ -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"); } } @@ -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(Count); - + ? ValuesGenerator.ArrayOfUniqueStrings(10 * 2, minLength: 25, maxLength: 25) + : ValuesGenerator.ArrayOfUniqueValues(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"); } } }