perf: Cache Stable Hashes (#3377)

* perf: Cache Stable Hashes
- Static dictionary of message hashes
- ResetStatics

* Added debug log for future debugging.

* Update Extensions.cs

---------

Co-authored-by: mischa <16416509+vis2k@users.noreply.github.com>
This commit is contained in:
MrGadget 2023-02-13 20:45:36 -05:00 committed by GitHub
parent 98212c5617
commit 59dc88c981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -9,15 +9,33 @@ public static class Extensions
public static string ToHexString(this ArraySegment<byte> 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<string, int> StableHashes = new Dictionary<string, int>();
[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;
}
}