From 7f54847ab8567bfba4e88afaf943ff7a40de95d2 Mon Sep 17 00:00:00 2001 From: Tim Pilius Date: Wed, 22 May 2024 11:12:08 -0400 Subject: [PATCH] Replacing current MD5.ToString() implementation with HexMate. HexMate is overall faster by a significant amount, around 7x speed improvement. Additionally this implementation is much easier to read and understand. --- BattleNetPrefill.sln.DotSettings | 1 + BattleNetPrefill/BattleNetPrefill.csproj | 3 +- .../Properties/launchSettings.json | 2 +- BattleNetPrefill/Structs/MD5Hash.cs | 65 ++++--------------- BattleNetPrefill/Structs/VersionsFile.cs | 5 -- BattleNetPrefill/Utils/HexConverter.cs | 33 ---------- 6 files changed, 16 insertions(+), 93 deletions(-) delete mode 100644 BattleNetPrefill/Utils/HexConverter.cs diff --git a/BattleNetPrefill.sln.DotSettings b/BattleNetPrefill.sln.DotSettings index ddd7013a..0912e57d 100644 --- a/BattleNetPrefill.sln.DotSettings +++ b/BattleNetPrefill.sln.DotSettings @@ -33,6 +33,7 @@ True True True + True True True True diff --git a/BattleNetPrefill/BattleNetPrefill.csproj b/BattleNetPrefill/BattleNetPrefill.csproj index 9f23da2c..693363fd 100644 --- a/BattleNetPrefill/BattleNetPrefill.csproj +++ b/BattleNetPrefill/BattleNetPrefill.csproj @@ -74,7 +74,8 @@ - + + diff --git a/BattleNetPrefill/Properties/launchSettings.json b/BattleNetPrefill/Properties/launchSettings.json index bf80e3d7..b24bef6e 100644 --- a/BattleNetPrefill/Properties/launchSettings.json +++ b/BattleNetPrefill/Properties/launchSettings.json @@ -22,7 +22,7 @@ }, "Prefill WOW - Compare Requests": { "commandName": "Project", - "commandLineArgs": "prefill -p s1 --compare-requests --no-download --force" + "commandLineArgs": "prefill -p wow_classic --compare-requests --no-download --force" }, "Select Apps": { "commandName": "Project", diff --git a/BattleNetPrefill/Structs/MD5Hash.cs b/BattleNetPrefill/Structs/MD5Hash.cs index 71803691..3638e2b8 100644 --- a/BattleNetPrefill/Structs/MD5Hash.cs +++ b/BattleNetPrefill/Structs/MD5Hash.cs @@ -1,4 +1,6 @@ -namespace BattleNetPrefill.Structs +using HexMate; + +namespace BattleNetPrefill.Structs { public readonly struct MD5Hash : IEquatable { @@ -12,7 +14,6 @@ public readonly ulong lowPart; [JsonInclude] - public readonly ulong highPart; #pragma warning restore SYSLIB1038 @@ -28,6 +29,7 @@ public override int GetHashCode() return Md5HashEqualityComparer.Instance.GetHashCode(this); } + //TODO benchmark equality again public bool Equals(MD5Hash other) { return other.lowPart == lowPart && other.highPart == highPart; @@ -39,63 +41,20 @@ public override bool Equals(object obj) return other.lowPart == lowPart && other.highPart == highPart; } - // TODO benchmark this and see if it is actually faster. Remove it otherwise public override string ToString() { - return string.Create(32, (highPart, lowPart), static (dst, state) => - { - ulong highPartTemp = state.highPart; - ulong lowPartTemp = state.lowPart; - - ulong lowMask = (ulong)15; - ulong highMask = 15 << 4; - int i = 0; - - while (i != 16) - { - dst[i] = HexConverter.ToCharUpper((uint)((lowPartTemp & highMask) >> 4)); - dst[i + 1] = HexConverter.ToCharUpper((uint)(lowPartTemp & lowMask)); - i += 2; - lowPartTemp >>= 8; - } - - while (i != 32) - { - dst[i] = HexConverter.ToCharUpper((uint)((highPartTemp & highMask) >> 4)); - dst[i + 1] = HexConverter.ToCharUpper((uint)(highPartTemp & lowMask)); - i += 2; - highPartTemp >>= 8; - } - }); + var bytes = new byte[16]; + BitConverter.TryWriteBytes(bytes.AsSpan(0, 8), lowPart); + BitConverter.TryWriteBytes(bytes.AsSpan(8, 8), highPart); + return HexMate.Convert.ToHexString(bytes); } public string ToStringLower() { - return string.Create(32, (highPart, lowPart), static (dst, state) => - { - ulong highPartTemp = state.highPart; - ulong lowPartTemp = state.lowPart; - - ulong lowMask = (ulong)15; - ulong highMask = 15 << 4; - int i = 0; - - while (i != 16) - { - dst[i] = HexConverter.ToCharLower((uint)((lowPartTemp & highMask) >> 4)); - dst[i + 1] = HexConverter.ToCharLower((uint)(lowPartTemp & lowMask)); - i += 2; - lowPartTemp >>= 8; - } - - while (i != 32) - { - dst[i] = HexConverter.ToCharLower((uint)((highPartTemp & highMask) >> 4)); - dst[i + 1] = HexConverter.ToCharLower((uint)(highPartTemp & lowMask)); - i += 2; - highPartTemp >>= 8; - } - }); + var bytes = new byte[16]; + BitConverter.TryWriteBytes(bytes.AsSpan(0, 8), lowPart); + BitConverter.TryWriteBytes(bytes.AsSpan(8, 8), highPart); + return HexMate.Convert.ToHexString(bytes, HexFormattingOptions.Lowercase); } public static bool operator ==(MD5Hash obj1, MD5Hash obj2) diff --git a/BattleNetPrefill/Structs/VersionsFile.cs b/BattleNetPrefill/Structs/VersionsFile.cs index dac55e09..0937559d 100644 --- a/BattleNetPrefill/Structs/VersionsFile.cs +++ b/BattleNetPrefill/Structs/VersionsFile.cs @@ -1,10 +1,5 @@ namespace BattleNetPrefill.Structs { - public struct VersionsFile - { - public VersionsEntry[] entries; - } - public struct VersionsEntry { public MD5Hash buildConfig; diff --git a/BattleNetPrefill/Utils/HexConverter.cs b/BattleNetPrefill/Utils/HexConverter.cs deleted file mode 100644 index f367c403..00000000 --- a/BattleNetPrefill/Utils/HexConverter.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace BattleNetPrefill.Utils -{ - public static class HexConverter - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static char ToCharUpper(uint value) - { - value &= 0xF; - value += '0'; - - if (value > '9') - { - value += ('A' - ('9' + 1)); - } - - return (char)value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static char ToCharLower(uint value) - { - value &= 0xF; - value += '0'; - - if (value > '9') - { - value += ('a' - ('9' + 1)); - } - - return (char)value; - } - } -}