diff --git a/Assets/Mirror/Core/Tools/Extensions.cs b/Assets/Mirror/Core/Tools/Extensions.cs index 3654e4b8c..28c91e560 100644 --- a/Assets/Mirror/Core/Tools/Extensions.cs +++ b/Assets/Mirror/Core/Tools/Extensions.cs @@ -9,15 +9,33 @@ public static class Extensions public static string ToHexString(this ArraySegment segment) => BitConverter.ToString(segment.Array, segment.Offset, segment.Count); + // GetStableHashCode is O(N). + // the longer the string, the more it needs to compute: + // https://github.com/MirrorNetworking/Mirror/pull/3377 + // cache results for O(1) lookups. + static readonly Dictionary StableHashes = new Dictionary(); + + [UnityEngine.RuntimeInitializeOnLoadMethod] + public static void ResetStatics() + { + StableHashes.Clear(); + } + // string.GetHashCode is not guaranteed to be the same on all machines, but // we need one that is the same on all machines. simple and stupid: public static int GetStableHashCode(this string text) { + if (StableHashes.TryGetValue(text, out int cachedHash)) + return cachedHash; + unchecked { int hash = 23; foreach (char c in text) hash = hash * 31 + c; + + //UnityEngine.Debug.Log($"Caching stable hash {(ushort)hash} for {text}"); + StableHashes[text] = hash; return hash; } }