From 38a4135bcda3edfeaecae91ec32abfb3d41b7e6d Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 20 Dec 2021 18:37:45 -0800 Subject: [PATCH] Span-ify the unpacking of mini arcs cuts out some of the internal c# sanity checking for better perf --- PKHeX.Core/Legality/BinLinker.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/PKHeX.Core/Legality/BinLinker.cs b/PKHeX.Core/Legality/BinLinker.cs index 393420ef7..f894a279a 100644 --- a/PKHeX.Core/Legality/BinLinker.cs +++ b/PKHeX.Core/Legality/BinLinker.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; namespace PKHeX.Core { @@ -10,22 +11,22 @@ public static class BinLinker /// Packed data /// Signature expected in the first two bytes (ASCII) /// Unpacked array containing all files that were packed. - public static byte[][] Unpack(byte[] fileData, string identifier) + public static byte[][] Unpack(ReadOnlySpan fileData, string identifier) { #if DEBUG System.Diagnostics.Debug.Assert(fileData.Length > 4); System.Diagnostics.Debug.Assert(identifier[0] == fileData[0] && identifier[1] == fileData[1]); #endif - int count = BitConverter.ToUInt16(fileData, 2); int ctr = 4; - int start = BitConverter.ToInt32(fileData, ctr); ctr += 4; + MemoryMarshal.TryRead(fileData[4..], out int start); + MemoryMarshal.TryRead(fileData[2..], out ushort count); + var offsetBytes = fileData[8..(8 + (count * sizeof(int)))]; + var offsets = MemoryMarshal.Cast(offsetBytes); + byte[][] returnData = new byte[count][]; - for (int i = 0; i < count; i++) + for (int i = 0; i < offsets.Length; i++) { - int end = BitConverter.ToInt32(fileData, ctr); ctr += 4; - int len = end - start; - byte[] data = new byte[len]; - Buffer.BlockCopy(fileData, start, data, 0, len); - returnData[i] = data; + int end = offsets[i]; + returnData[i] = fileData[start..end].ToArray(); start = end; } return returnData;