|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Text;
namespace System.Collections.Frozen
{
/// <summary>
/// A few numbers to drive implementation selection heuristics.
/// </summary>
/// <remarks>
/// These numbers were arrived through simple benchmarks conducted against .NET 7.
/// It's worth potentially tweaking these values if the implementation of the
/// collections changes in a substantial way, or if the JIT improves related code gen over time.
/// </remarks>
internal static class Constants
{
/// <summary>Threshold when we switch from scanning to hashing for non-value-type or non-default-comparer collections.</summary>
/// <remarks>
/// This determines the threshold where we switch from
/// the scanning-based SmallFrozenDictionary/Set to the hashing-based
/// DefaultFrozenDictionary/Set.
/// </remarks>
public const int MaxItemsInSmallFrozenCollection = 4;
/// <summary>Threshold when we switch from scanning to hashing value type collections using a default comparer.</summary>
/// <remarks>
/// This determines the threshold when we switch from the scanning
/// SmallValueTypeDefaultComparerFrozenDictionary/Set to the
/// hashing ValueTypeDefaultComparerFrozenDictionary/Set.
/// </remarks>
public const int MaxItemsInSmallValueTypeFrozenCollection = 10;
/// <summary>
/// Whether the <typeparamref name="T"/> is known to implement <see cref="IComparable{T}"/> safely and efficiently,
/// such that its comparison operations should be used in searching for types in small collections.
/// </summary>
/// <remarks>
/// This does not automatically return true for any type that implements <see cref="IComparable{T}"/>.
/// Doing so leads to problems for container types (e.g. ValueTuple{T1, T2}) where the
/// container implements <see cref="IComparable{T}"/> to delegate to its contained items' implementation
/// but those then don't provide such support.
/// </remarks>
public static bool IsKnownComparable<T>() =>
// This list covers all of the IComparable<T> value types in Corelib that aren't containers (like ValueTuple).
typeof(T) == typeof(bool) ||
typeof(T) == typeof(sbyte) ||
typeof(T) == typeof(byte) ||
typeof(T) == typeof(char) ||
typeof(T) == typeof(short) ||
typeof(T) == typeof(ushort) ||
typeof(T) == typeof(int) ||
typeof(T) == typeof(uint) ||
typeof(T) == typeof(long) ||
typeof(T) == typeof(ulong) ||
typeof(T) == typeof(decimal) ||
typeof(T) == typeof(float) ||
typeof(T) == typeof(double) ||
typeof(T) == typeof(decimal) ||
typeof(T) == typeof(TimeSpan) ||
typeof(T) == typeof(DateTime) ||
typeof(T) == typeof(DateTimeOffset) ||
typeof(T) == typeof(Guid) ||
#if NET
typeof(T) == typeof(Rune) ||
typeof(T) == typeof(Half) ||
typeof(T) == typeof(nint) ||
typeof(T) == typeof(nuint) ||
typeof(T) == typeof(DateOnly) ||
typeof(T) == typeof(TimeOnly) ||
typeof(T) == typeof(Int128) ||
typeof(T) == typeof(UInt128) ||
#endif
typeof(T).IsEnum;
// for these types GetHashCode returns their value casted to int, so when we receive a Dictionary/HashSet where there are key
// we know that all hash codes are unique and we can avoid some work later
internal static bool KeysAreHashCodes<T>()
=> typeof(T) == typeof(int) || typeof(T) == typeof(uint)
|| typeof(T) == typeof(short) || typeof(T) == typeof(ushort)
|| typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte)
|| ((typeof(T) == typeof(nint) || typeof(T) == typeof(nuint)) && IntPtr.Size == 4);
}
}
|