Avoid `string.Split` in `Database.InitializeWork`

On my machine (Mono) in Release config, this reduces the number of
string- and char-arrays allocated by an order of magnitude,
bringing the gamedb's total bytes allocated down by -10%.
This commit is contained in:
YoshiRulz 2024-10-24 06:20:22 +10:00
parent 6f3fd9740e
commit 4c69ce4e27
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
1 changed files with 21 additions and 13 deletions

View File

@ -97,10 +97,18 @@ namespace BizHawk.Emulation.Common
public static CompactGameInfo ParseCGIRecord(string line) public static CompactGameInfo ParseCGIRecord(string line)
{ {
const char FIELD_SEPARATOR = '\t'; const char FIELD_SEPARATOR = '\t';
var items = line.Split(FIELD_SEPARATOR); var iFieldStart = -1;
var field = 0; var iFieldEnd = -1; // offset of the tab char, or line.Length if at end
var hashDigest = FormatHash(items[field++]); string AdvanceAndReadField(out bool isLastField)
var dumpStatus = items[field++].Trim() switch {
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
{ {
"B" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt "B" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt
"V" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt "V" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt
@ -112,21 +120,21 @@ namespace BizHawk.Emulation.Common
"U" => RomStatus.Unknown, "U" => RomStatus.Unknown,
_ => RomStatus.GoodDump _ => RomStatus.GoodDump
}; };
var knownName = items[field++]; var knownName = AdvanceAndReadField(out _);
var sysID = items[field++]; var sysID = AdvanceAndReadField(out var isLastField);
string/*?*/ metadata = null; string/*?*/ metadata = null;
string region = string.Empty; string region = string.Empty;
string forcedCore = string.Empty; string forcedCore = string.Empty;
if (field < items.Length) if (!isLastField)
{ {
_ = items[field++]; // rarely populated; possibly genre or just a remark _ = AdvanceAndReadField(out isLastField); // rarely present; possibly genre or just a remark
if (field < items.Length) if (!isLastField)
{ {
metadata = items[field++]; metadata = AdvanceAndReadField(out isLastField);
if (field < items.Length) if (!isLastField)
{ {
region = items[field++]; region = AdvanceAndReadField(out isLastField);
if (field < items.Length) forcedCore = items[field++]; if (!isLastField) forcedCore = AdvanceAndReadField(out isLastField);
} }
} }
} }