From 8645ed3bb9fd62c0d42cb7ceff816fc5bf0c9d92 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sun, 15 Dec 2024 13:49:46 +1000 Subject: [PATCH] Optimise `Database.FormatHash` runtime (as reported by `Database`) reduced by -14%, allocations reduced by -5%, and number of calls reduced by -32% this is all under Mono so YMMV --- .../Extensions/StringExtensions.cs | 21 +++++++++++++++++++ .../Database/Database.cs | 5 ++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/BizHawk.Common/Extensions/StringExtensions.cs b/src/BizHawk.Common/Extensions/StringExtensions.cs index 400ec5dc8e2..2d81f34716f 100644 --- a/src/BizHawk.Common/Extensions/StringExtensions.cs +++ b/src/BizHawk.Common/Extensions/StringExtensions.cs @@ -183,6 +183,27 @@ public static byte[] ToCharCodepointArray(this string str) return a; } + /// as , but assumes is 7-bit ASCII to allow for an optimisation + /// allocates a new char array only when necessary + public static string ToUpperASCIIFast(this string str) + { + const ushort ASCII_UPCASE_MASK = 0b101111; + for (var i = 0; i < str.Length; i++) + { + if (str[i] is < 'a' or > 'z') continue; + var a = new char[str.Length]; + str.AsSpan(start: 0, length: i).CopyTo(a); + a[i] = unchecked((char) (str[i] & ASCII_UPCASE_MASK)); + while (++i < str.Length) + { + var c = str[i]; + a[i] = c is >= 'a' and <= 'z' ? unchecked((char) (c & ASCII_UPCASE_MASK)) : c; + } + return new(a); + } + return str; + } + /// /// splits a given by , /// applies to each part, then rejoins them diff --git a/src/BizHawk.Emulation.Common/Database/Database.cs b/src/BizHawk.Emulation.Common/Database/Database.cs index 4cf2de773a8..4675338e9b5 100644 --- a/src/BizHawk.Emulation.Common/Database/Database.cs +++ b/src/BizHawk.Emulation.Common/Database/Database.cs @@ -36,7 +36,10 @@ public static class Database /// The hash to format, this is typically prefixed with a type (e.g. sha1:) /// formatted hash private static string FormatHash(string hash) - => hash.Substring(hash.IndexOf(':') + 1).ToUpperInvariant(); + { + var i = hash.IndexOf(':'); + return (i < 0 ? hash.Substring(startIndex: i + 1) : hash).ToUpperASCIIFast(); + } private static void LoadDatabase_Escape(string line, bool inUser, bool silent) {