From c2200cb234ebcd174ec323972f6cb82eae8feefa Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sun, 15 Dec 2024 14:40:09 +1000 Subject: [PATCH] Use allocless `ReadOnlySpan.Split` in `Database.InitializeWork` reverts 4c69ce4e2 --- .../Extensions/CollectionExtensions.cs | 18 ++++++++ .../Database/Database.cs | 41 +++++++++---------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/BizHawk.Common/Extensions/CollectionExtensions.cs b/src/BizHawk.Common/Extensions/CollectionExtensions.cs index 8e89495826..7f49167b62 100644 --- a/src/BizHawk.Common/Extensions/CollectionExtensions.cs +++ b/src/BizHawk.Common/Extensions/CollectionExtensions.cs @@ -292,6 +292,24 @@ public static bool ReversedSequenceEqual(this ReadOnlySpan a, ReadOnlySpan return true; } + public static ReadOnlySpan Slice(this ReadOnlySpan span, Range range) + { + var (offset, length) = range.GetOffsetAndLength(span.Length); + return span.Slice(start: offset, length: length); + } + + public static Span Slice(this Span span, Range range) + { + var (offset, length) = range.GetOffsetAndLength(span.Length); + return span.Slice(start: offset, length: length); + } + + public static string Substring(this string str, Range range) + { + var (offset, length) = range.GetOffsetAndLength(str.Length); + return str.Substring(startIndex: offset, length: length); + } + /// shallow clone public static Dictionary ToDictionary(this IEnumerable> list) => list.ToDictionary(static kvp => kvp.Key, static kvp => kvp.Value); diff --git a/src/BizHawk.Emulation.Common/Database/Database.cs b/src/BizHawk.Emulation.Common/Database/Database.cs index 257aecea1f..bbd36e1a94 100644 --- a/src/BizHawk.Emulation.Common/Database/Database.cs +++ b/src/BizHawk.Emulation.Common/Database/Database.cs @@ -9,6 +9,7 @@ using System.Threading; using BizHawk.Common; +using BizHawk.Common.CollectionExtensions; using BizHawk.Common.StringExtensions; namespace BizHawk.Emulation.Common @@ -102,21 +103,15 @@ public static void SaveDatabaseEntry(CompactGameInfo gameInfo, string filename = private static bool initialized = false; - public static CompactGameInfo ParseCGIRecord(string line) + public static CompactGameInfo ParseCGIRecord(string lineStr) { + var line = lineStr.AsSpan(); const char FIELD_SEPARATOR = '\t'; - var iFieldStart = -1; - var iFieldEnd = -1; // offset of the tab char, or line.Length if at end - string AdvanceAndReadField(out bool isLastField) - { - iFieldStart = iFieldEnd + 1; - iFieldEnd = line.IndexOf(FIELD_SEPARATOR, iFieldStart); - isLastField = iFieldEnd < 0; - if (isLastField) iFieldEnd = line.Length; - return line.Substring(startIndex: iFieldStart, length: iFieldEnd - iFieldStart); - } - var hashDigest = FormatHash(AdvanceAndReadField(out _)); - var dumpStatus = AdvanceAndReadField(out _).Trim() switch + var iter = line.Split(FIELD_SEPARATOR); + _ = iter.MoveNext(); + var hashDigest = FormatHash(lineStr.Substring(iter.Current)); + _ = iter.MoveNext(); + var dumpStatus = line.Slice(iter.Current).Trim() switch { "B" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt "V" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt @@ -128,21 +123,23 @@ string AdvanceAndReadField(out bool isLastField) "U" => RomStatus.Unknown, _ => RomStatus.GoodDump }; - var knownName = AdvanceAndReadField(out _); - var sysID = AdvanceAndReadField(out var isLastField); + _ = iter.MoveNext(); + var knownName = lineStr.Substring(iter.Current); + _ = iter.MoveNext(); + var sysID = lineStr.Substring(iter.Current); string/*?*/ metadata = null; string region = string.Empty; string forcedCore = string.Empty; - if (!isLastField) + if (iter.MoveNext()) { - _ = AdvanceAndReadField(out isLastField); // rarely present; possibly genre or just a remark - if (!isLastField) + //_ = line.Slice(iter.Current); // rarely populated; possibly genre or just a remark + if (iter.MoveNext()) { - metadata = AdvanceAndReadField(out isLastField); - if (!isLastField) + metadata = lineStr.Substring(iter.Current); + if (iter.MoveNext()) { - region = AdvanceAndReadField(out isLastField); - if (!isLastField) forcedCore = AdvanceAndReadField(out isLastField); + region = lineStr.Substring(iter.Current); + if (iter.MoveNext()) forcedCore = lineStr.Substring(iter.Current); } } }