Skip to content

Commit

Permalink
Avoid string.Split in Database.InitializeWork
Browse files Browse the repository at this point in the history
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%.
  • Loading branch information
YoshiRulz committed Oct 23, 2024
1 parent 6f3fd97 commit 4c69ce4
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/BizHawk.Emulation.Common/Database/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,18 @@ public static void SaveDatabaseEntry(CompactGameInfo gameInfo, string filename =
public static CompactGameInfo ParseCGIRecord(string line)
{
const char FIELD_SEPARATOR = '\t';
var items = line.Split(FIELD_SEPARATOR);
var field = 0;
var hashDigest = FormatHash(items[field++]);
var dumpStatus = items[field++].Trim() switch
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
{
"B" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt
"V" => RomStatus.BadDump, // see /Assets/gamedb/gamedb.txt
Expand All @@ -112,21 +120,21 @@ public static CompactGameInfo ParseCGIRecord(string line)
"U" => RomStatus.Unknown,
_ => RomStatus.GoodDump
};
var knownName = items[field++];
var sysID = items[field++];
var knownName = AdvanceAndReadField(out _);
var sysID = AdvanceAndReadField(out var isLastField);
string/*?*/ metadata = null;
string region = string.Empty;
string forcedCore = string.Empty;
if (field < items.Length)
if (!isLastField)
{
_ = items[field++]; // rarely populated; possibly genre or just a remark
if (field < items.Length)
_ = AdvanceAndReadField(out isLastField); // rarely present; possibly genre or just a remark
if (!isLastField)
{
metadata = items[field++];
if (field < items.Length)
metadata = AdvanceAndReadField(out isLastField);
if (!isLastField)
{
region = items[field++];
if (field < items.Length) forcedCore = items[field++];
region = AdvanceAndReadField(out isLastField);
if (!isLastField) forcedCore = AdvanceAndReadField(out isLastField);
}
}
}
Expand Down

0 comments on commit 4c69ce4

Please sign in to comment.