From d95ba482f3e3b2aa91e3442f0d33aeee618690a3 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 13 Mar 2022 19:39:38 -0700 Subject: [PATCH] Reduce allocation in methodfinder IV set --- .../Applicators/HiddenPowerApplicator.cs | 9 ++++-- .../Editing/Applicators/MarkingApplicator.cs | 4 ++- PKHeX.Core/Editing/CommonEdits.cs | 2 +- .../EncounterStatic/EncounterStatic.cs | 2 +- .../EncounterTrade/EncounterTrade.cs | 2 +- PKHeX.Core/Legality/RNG/MethodFinder.cs | 31 +++++-------------- PKHeX.Core/Legality/RNG/PIDGenerator.cs | 17 +++++++--- PKHeX.Core/PKM/PKM.cs | 2 +- 8 files changed, 33 insertions(+), 36 deletions(-) diff --git a/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs b/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs index 065ed5959..a309676a1 100644 --- a/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs +++ b/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs @@ -1,4 +1,6 @@ -namespace PKHeX.Core +using System; + +namespace PKHeX.Core { public static class HiddenPowerApplicator { @@ -9,9 +11,10 @@ public static class HiddenPowerApplicator /// Desired Hidden Power typing. public static void SetHiddenPower(this PKM pk, int hiddenPowerType) { - var IVs = pk.IVs; + Span IVs = stackalloc int[6]; + pk.GetIVs(IVs); HiddenPower.SetIVsForType(hiddenPowerType, IVs, pk.Format); - pk.IVs = IVs; + pk.SetIVs(IVs); } /// diff --git a/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs b/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs index 5189f9f57..ce0c4745e 100644 --- a/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs +++ b/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs @@ -40,7 +40,9 @@ public static void SetMarkings(this PKM pk) if (pk.Format <= 3) return; // no markings (gen3 only has 4; can't mark stats intelligently - pk.SetMarkings(pk.IVs); + Span IVs = stackalloc int[6]; + pk.GetIVs(IVs); + pk.SetMarkings(IVs); } /// diff --git a/PKHeX.Core/Editing/CommonEdits.cs b/PKHeX.Core/Editing/CommonEdits.cs index 4b8621f04..c247d7ea5 100644 --- a/PKHeX.Core/Editing/CommonEdits.cs +++ b/PKHeX.Core/Editing/CommonEdits.cs @@ -174,7 +174,7 @@ public static void ApplySetDetails(this PKM pk, IBattleTemplate Set) pk.ApplyHeldItem(Set.HeldItem, Set.Format); pk.CurrentLevel = Set.Level; pk.CurrentFriendship = Set.Friendship; - pk.IVs = Set.IVs; + pk.SetIVs(Set.IVs); if (pk is GBPKM gb) { diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs index a4cadeda6..144abc0d9 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs @@ -166,7 +166,7 @@ private void SetEncounterMoves(PKM pk, GameVersion version, int level) protected void SetIVs(PKM pk) { if (IVs.Count != 0) - pk.SetRandomIVs(IVs, FlawlessIVCount); + pk.SetRandomIVs((int[])IVs, FlawlessIVCount); else if (FlawlessIVCount > 0) pk.SetRandomIVs(flawless: FlawlessIVCount); } diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs index cde65bc7d..5647b4b88 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs @@ -151,7 +151,7 @@ protected virtual void SetPINGA(PKM pk, EncounterCriteria criteria) protected void SetIVs(PKM pk) { if (IVs.Count != 0) - pk.SetRandomIVs(IVs, 0); + pk.SetRandomIVs((int[])IVs, 0); else pk.SetRandomIVs(flawless: 3); } diff --git a/PKHeX.Core/Legality/RNG/MethodFinder.cs b/PKHeX.Core/Legality/RNG/MethodFinder.cs index b5377322a..60ac26b34 100644 --- a/PKHeX.Core/Legality/RNG/MethodFinder.cs +++ b/PKHeX.Core/Legality/RNG/MethodFinder.cs @@ -722,33 +722,18 @@ private static bool IVsMatch(uint r1, uint r2, ReadOnlySpan IVs) /// /// Generates IVs from 2 RNG calls using 15 bits of each to generate 6 IVs (5bits each). /// + /// Result storage /// First rand frame /// Second rand frame /// Array of 6 IVs - internal static uint[] GetIVs(uint r1, uint r2) + internal static void GetIVsInt32(Span result, uint r1, uint r2) { - return new[] - { - r1 & 31, - r1 >> 5 & 31, - r1 >> 10 & 31, - r2 & 31, - r2 >> 5 & 31, - r2 >> 10 & 31, - }; - } - - internal static int[] GetIVsInt32(uint r1, uint r2) - { - return new[] - { - (int)r1 & 31, - (int)r1 >> 5 & 31, - (int)r1 >> 10 & 31, - (int)r2 & 31, - (int)r2 >> 5 & 31, - (int)r2 >> 10 & 31, - }; + result[5] = (int)r2 >> 10 & 31; + result[4] = (int)r2 >> 5 & 31; + result[3] = (int)r2 & 31; + result[2] = (int)r1 >> 10 & 31; + result[1] = (int)r1 >> 5 & 31; + result[0] = (int)r1 & 31; } private static uint GetIVChunk(ReadOnlySpan IVs, int start) diff --git a/PKHeX.Core/Legality/RNG/PIDGenerator.cs b/PKHeX.Core/Legality/RNG/PIDGenerator.cs index 477a0085e..63d47604e 100644 --- a/PKHeX.Core/Legality/RNG/PIDGenerator.cs +++ b/PKHeX.Core/Legality/RNG/PIDGenerator.cs @@ -32,7 +32,8 @@ private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed) if (skipIV2Frame) // VBlank skip between IVs D = rng.Next(D); - var IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); + Span IVs = stackalloc int[6]; + MethodFinder.GetIVsInt32(IVs, C >> 16, D >> 16); if (type == PIDType.Method_1_Roamer) { // Only store lowest 8 bits of IV data; zero out the other bits. @@ -40,7 +41,7 @@ private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed) for (int i = 2; i < 6; i++) IVs[i] = 0; } - pk.IVs = IVs; + pk.SetIVs(IVs); } private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed) @@ -71,7 +72,9 @@ private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed) pk.PID = (A & 0xFFFF0000) | B >> 16; } - pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); + Span IVs = stackalloc int[6]; + MethodFinder.GetIVsInt32(IVs, C >> 16, D >> 16); + pk.SetIVs(IVs); bool antishiny = type is PIDType.BACD_R_A or PIDType.BACD_U_A; while (antishiny && pk.IsShiny) @@ -101,7 +104,9 @@ private static void SetValuesFromSeedXDRNG(PKM pk, uint seed) var E = rng.Next(D); // PID pk.PID = (D & 0xFFFF0000) | E >> 16; - pk.IVs = MethodFinder.GetIVsInt32(A >> 16, B >> 16); + Span IVs = stackalloc int[6]; + MethodFinder.GetIVsInt32(IVs, A >> 16, B >> 16); + pk.SetIVs(IVs); } public static void SetValuesFromSeedXDRNG_EReader(PKM pk, uint seed) @@ -207,7 +212,9 @@ public static void SetRandomChainShinyPID(PKM pk, uint seed) upper = ((uint)(lower ^ pk.TID ^ pk.SID) & 0xFFF8) | (upper & 0x7); pk.PID = upper << 16 | lower; - pk.IVs = MethodFinder.GetIVsInt32(Next(), Next()); + Span IVs = stackalloc int[6]; + MethodFinder.GetIVsInt32(IVs, Next(), Next()); + pk.SetIVs(IVs); } public static void SetRandomPokeSpotPID(PKM pk, int nature, int gender, int ability, int slot) diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index c5bcad616..00ed3d851 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -972,7 +972,7 @@ public int[] SetRandomIVsGO(int minIV = 0, int maxIV = 15) /// IV template to generate from /// Count of flawless IVs to set. If none provided, a count will be detected. /// Randomized IVs if desired. - public int[] SetRandomIVs(IReadOnlyList template, int? flawless = null) + public int[] SetRandomIVs(ReadOnlySpan template, int? flawless = null) { int count = flawless ?? GetFlawlessIVCount(); int[] ivs = new int[6];