From c40c3905e2836e8b105406430c33659a84c2e3ca Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Wed, 19 Oct 2022 01:31:34 +0200 Subject: [PATCH] Avoid allocations in .Parse methods (#3760) * Avoid allocations in .Parse methods Use the Span overloads of the Parse methods when possible to avoid string allocations and remove one unnecessarry array allocation * Avoid another string allocation --- Ryujinx.Common/Utilities/EmbeddedResources.cs | 2 +- Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs | 2 +- Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs | 10 +++++----- Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs | 3 +-- Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs | 2 +- Ryujinx.HLE/Utilities/StringUtils.cs | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Ryujinx.Common/Utilities/EmbeddedResources.cs b/Ryujinx.Common/Utilities/EmbeddedResources.cs index 6113bc72..286d2c5c 100644 --- a/Ryujinx.Common/Utilities/EmbeddedResources.cs +++ b/Ryujinx.Common/Utilities/EmbeddedResources.cs @@ -129,7 +129,7 @@ namespace Ryujinx.Common private static (Assembly, string) ResolveManifestPath(string filename) { - var segments = filename.Split(new[] { '/' }, 2, StringSplitOptions.RemoveEmptyEntries); + var segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries); if (segments.Length >= 2) { diff --git a/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs b/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs index 1e621121..be5b7539 100644 --- a/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs +++ b/Ryujinx.HLE/HOS/Diagnostics/Demangler/Demangler.cs @@ -918,7 +918,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler return -1; } - return int.Parse(part.Substring(0, numberLength)); + return int.Parse(part.AsSpan(0, numberLength)); } private string ParseNumber(bool isSigned = false) diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs index 9dfa677c..fc0c0647 100644 --- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs +++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs @@ -816,11 +816,11 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp Reserved = new Array57() }; - modelInfo.CharacterId = BinaryPrimitives.ReverseEndianness(ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(0, 4), NumberStyles.HexNumber)); - modelInfo.CharacterVariant = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(4, 2), NumberStyles.HexNumber); - modelInfo.Series = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(12, 2), NumberStyles.HexNumber); - modelInfo.ModelNumber = ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(8, 4), NumberStyles.HexNumber); - modelInfo.Type = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(6, 2), NumberStyles.HexNumber); + modelInfo.CharacterId = BinaryPrimitives.ReverseEndianness(ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(0, 4), NumberStyles.HexNumber)); + modelInfo.CharacterVariant = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(4, 2), NumberStyles.HexNumber); + modelInfo.Series = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(12, 2), NumberStyles.HexNumber); + modelInfo.ModelNumber = ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(8, 4), NumberStyles.HexNumber); + modelInfo.Type = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(6, 2), NumberStyles.HexNumber); context.Memory.Write(outputPosition, modelInfo); diff --git a/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs b/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs index d34f4cf8..e85d99c7 100644 --- a/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs +++ b/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs @@ -122,9 +122,8 @@ namespace Ryujinx.HLE.HOS.Tamper for (int nybbleIndex = 0; nybbleIndex < wordSize; nybbleIndex++) { int index = wordIndex * wordSize + nybbleIndex; - string byteData = word.Substring(nybbleIndex, 1); - instruction[index] = byte.Parse(byteData, NumberStyles.HexNumber, CultureInfo.InvariantCulture); + instruction[index] = byte.Parse(word.AsSpan(nybbleIndex, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture); } } diff --git a/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs b/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs index 8cc03d05..416fc1b4 100644 --- a/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs +++ b/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs @@ -132,7 +132,7 @@ namespace Ryujinx.HLE.Loaders.Mods { if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { - return int.TryParse(str.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out value); + return int.TryParse(str.AsSpan(2), System.Globalization.NumberStyles.HexNumber, null, out value); } else { diff --git a/Ryujinx.HLE/Utilities/StringUtils.cs b/Ryujinx.HLE/Utilities/StringUtils.cs index 269f9b55..a64d451c 100644 --- a/Ryujinx.HLE/Utilities/StringUtils.cs +++ b/Ryujinx.HLE/Utilities/StringUtils.cs @@ -54,7 +54,7 @@ namespace Ryujinx.HLE.Utilities for (int index = 0; index < bytesInHex; index++) { - output[index] = byte.Parse(hexString.Substring(index * 2, 2), NumberStyles.HexNumber); + output[index] = byte.Parse(hexString.AsSpan(index * 2, 2), NumberStyles.HexNumber); } return output;