From 8f9de863472287622fc820173938dd9be025505b Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 6 Mar 2022 13:04:56 -0800 Subject: [PATCH] Span-ify BreedInfo, saves 10bytes heap alloc the Actual result still needs to leave the stack, so that has to be heap allocated. --- .../Encounters/Verifiers/VerifyCurrentMoves.cs | 10 +++++----- PKHeX.Core/Legality/Moves/Breeding/BreedInfo.cs | 10 +++++----- PKHeX.Core/Legality/Moves/Breeding/MoveBreed.cs | 4 ++-- PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs | 14 ++++++++------ PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs | 14 ++++++++------ PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs | 14 ++++++++------ PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs | 14 ++++++++------ PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs | 14 ++++++++------ 8 files changed, 52 insertions(+), 42 deletions(-) diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs index 4caaa7db8..a18620514 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs @@ -655,7 +655,7 @@ namespace PKHeX.Core private static bool IsCheckInvalid(CheckResult? chk) => !(chk?.Valid ?? false); private static bool IsCheckValid(CheckResult? chk) => chk?.Valid ?? false; - private static void FlagIncompatibleTransferHMs45(CheckMoveResult[] res, IReadOnlyList currentMoves, int gen, IReadOnlyList HMLearned, bool KnowDefogWhirlpool) + private static void FlagIncompatibleTransferHMs45(CheckMoveResult[] res, IReadOnlyList currentMoves, int gen, ReadOnlySpan HMLearned, bool KnowDefogWhirlpool) { // After all the moves from the generations 3 and 4, // including egg moves if is the origin generation because some hidden moves are also special egg moves in gen 3 @@ -675,7 +675,7 @@ namespace PKHeX.Core } // Flag moves that are only legal when learned from a past-gen HM source - for (int i = 0; i < HMLearned.Count; i++) + for (int i = 0; i < HMLearned.Length; i++) { if (HMLearned[i] && IsCheckValid(res[i])) res[i] = new CheckMoveResult(res[i], Invalid, string.Format(LTransferMoveHM, gen, gen + 1), CurrentMove); @@ -689,7 +689,7 @@ namespace PKHeX.Core return result; } - private static void VerifyNoEmptyDuplicates(IReadOnlyList moves, CheckMoveResult[] res) + private static void VerifyNoEmptyDuplicates(ReadOnlySpan moves, CheckMoveResult[] res) { bool emptySlot = false; for (int i = 0; i < 4; i++) @@ -714,7 +714,7 @@ namespace PKHeX.Core } } - private static void FlagDuplicateMovesAfterIndex(IReadOnlyList moves, CheckMoveResult[] res, int index, int move) + private static void FlagDuplicateMovesAfterIndex(ReadOnlySpan moves, CheckMoveResult[] res, int index, int move) { for (int i = index + 1; i < 4; i++) { @@ -725,7 +725,7 @@ namespace PKHeX.Core } } - private static void FlagEmptySlotsBeforeIndex(IReadOnlyList moves, CheckMoveResult[] res, int index) + private static void FlagEmptySlotsBeforeIndex(ReadOnlySpan moves, CheckMoveResult[] res, int index) { for (int i = index - 1; i >= 0; i--) { diff --git a/PKHeX.Core/Legality/Moves/Breeding/BreedInfo.cs b/PKHeX.Core/Legality/Moves/Breeding/BreedInfo.cs index 9f8d1adda..bd884556b 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/BreedInfo.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/BreedInfo.cs @@ -12,21 +12,21 @@ namespace PKHeX.Core public readonly T[] Actual; /// Indicates all possible sources of each move. - public readonly byte[] Possible; + public readonly Span Possible; /// Level Up entry for the egg. public readonly Learnset Learnset; /// Moves the egg knows after it is finalized. - public readonly int[] Moves; + public readonly ReadOnlySpan Moves; /// Level the egg originated at. public readonly int Level; - public BreedInfo(int count, Learnset learnset, int[] moves, int level) + public BreedInfo(T[] actual, Span possible, Learnset learnset, ReadOnlySpan moves, int level) { - Possible = new byte[count]; - Actual = new T[count]; + Actual = actual; + Possible = possible; Learnset = learnset; Moves = moves; Level = level; diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed.cs index 11f3ebcd9..ed59f1db6 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed.cs @@ -12,7 +12,7 @@ namespace PKHeX.Core return valid; } - public static object Process(int generation, int species, int form, GameVersion version, int[] moves, out bool valid) => generation switch + public static object Process(int generation, int species, int form, GameVersion version, ReadOnlySpan moves, out bool valid) => generation switch { 2 => MoveBreed2.Validate(species, version, moves, out valid), 3 => MoveBreed3.Validate(species, version, moves, out valid), @@ -29,7 +29,7 @@ namespace PKHeX.Core return GetExpectedMoves(enc.Generation, enc.Species, enc.Form, enc.Version, moves, parse); } - public static int[] GetExpectedMoves(int generation, int species, int form, GameVersion version, int[] moves, object parse) + public static int[] GetExpectedMoves(int generation, int species, int form, GameVersion version, ReadOnlySpan moves, object parse) { // Try rearranging the order of the moves. // Build an info table diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs index c42afe38a..19bf948d9 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs @@ -9,9 +9,9 @@ namespace PKHeX.Core { private const int level = 5; - public static EggSource2[] Validate(int species, GameVersion version, int[] moves, out bool valid) + public static EggSource2[] Validate(int species, GameVersion version, ReadOnlySpan moves, out bool valid) { - var count = Array.IndexOf(moves, 0); + var count = moves.IndexOf(0); if (count == 0) { valid = false; // empty moveset @@ -26,7 +26,9 @@ namespace PKHeX.Core var pi = table[species]; var egg = (version == GameVersion.C ? Legal.EggMovesC : Legal.EggMovesGS)[species].Moves; - var value = new BreedInfo(count, learnset, moves, level); + var actual = new EggSource2[count]; + Span possible = stackalloc byte[count]; + var value = new BreedInfo(actual, possible, learnset, moves, level); { bool inherit = Breeding.GetCanInheritMoves(species); MarkMovesForOrigin(value, egg, count, inherit, pi, version); @@ -34,11 +36,11 @@ namespace PKHeX.Core } if (!valid) - CleanResult(value.Actual, value.Possible); - return value.Actual; + CleanResult(actual, possible); + return actual; } - private static void CleanResult(EggSource2[] valueActual, byte[] valuePossible) + private static void CleanResult(EggSource2[] valueActual, Span valuePossible) { for (int i = 0; i < valueActual.Length; i++) { diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs index 669f05c61..dbf3a59d7 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs @@ -13,9 +13,9 @@ namespace PKHeX.Core { private const int level = 5; - public static EggSource34[] Validate(int species, GameVersion version, int[] moves, out bool valid) + public static EggSource34[] Validate(int species, GameVersion version, ReadOnlySpan moves, out bool valid) { - var count = Array.IndexOf(moves, 0); + var count = moves.IndexOf(0); if (count == 0) { valid = false; // empty moveset @@ -30,9 +30,11 @@ namespace PKHeX.Core var pi = table[species]; var egg = Legal.EggMovesRS[species].Moves; - var value = new BreedInfo(count, learnset, moves, level); + var actual = new EggSource34[count]; + Span possible = stackalloc byte[count]; + var value = new BreedInfo(actual, possible, learnset, moves, level); if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle && version == GameVersion.E) - value.Actual[--count] = VoltTackle; + actual[--count] = VoltTackle; if (count == 0) { @@ -46,11 +48,11 @@ namespace PKHeX.Core } if (!valid) - CleanResult(value.Actual, value.Possible); + CleanResult(actual, possible); return value.Actual; } - private static void CleanResult(EggSource34[] valueActual, byte[] valuePossible) + private static void CleanResult(EggSource34[] valueActual, Span valuePossible) { for (int i = 0; i < valueActual.Length; i++) { diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs index 164d3c2d4..726b4bcc9 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs @@ -14,9 +14,9 @@ namespace PKHeX.Core { private const int level = 1; - public static EggSource34[] Validate(int species, GameVersion version, int[] moves, out bool valid) + public static EggSource34[] Validate(int species, GameVersion version, ReadOnlySpan moves, out bool valid) { - var count = Array.IndexOf(moves, 0); + var count = moves.IndexOf(0); if (count == 0) { valid = false; // empty moveset @@ -31,9 +31,11 @@ namespace PKHeX.Core var pi = table[species]; var egg = (version is HG or SS ? Legal.EggMovesHGSS : Legal.EggMovesDPPt)[species].Moves; - var value = new BreedInfo(count, learnset, moves, level); + var actual = new EggSource34[count]; + Span possible = stackalloc byte[count]; + var value = new BreedInfo(actual, possible, learnset, moves, level); if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle) - value.Actual[--count] = VoltTackle; + actual[--count] = VoltTackle; if (count == 0) { @@ -47,11 +49,11 @@ namespace PKHeX.Core } if (!valid) - CleanResult(value.Actual, value.Possible); + CleanResult(actual, possible); return value.Actual; } - private static void CleanResult(EggSource34[] valueActual, byte[] valuePossible) + private static void CleanResult(EggSource34[] valueActual, Span valuePossible) { for (int i = 0; i < valueActual.Length; i++) { diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs index dea5688af..6efe93f57 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs @@ -13,9 +13,9 @@ namespace PKHeX.Core { private const int level = 1; - public static EggSource5[] Validate(int species, GameVersion version, int[] moves, out bool valid) + public static EggSource5[] Validate(int species, GameVersion version, ReadOnlySpan moves, out bool valid) { - var count = Array.IndexOf(moves, 0); + var count = moves.IndexOf(0); if (count == 0) { valid = false; // empty moveset @@ -30,9 +30,11 @@ namespace PKHeX.Core var pi = table[species]; var egg = Legal.EggMovesBW[species].Moves; - var value = new BreedInfo(count, learnset, moves, level); + var actual = new EggSource5[count]; + Span possible = stackalloc byte[count]; + var value = new BreedInfo(actual, possible, learnset, moves, level); if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle) - value.Actual[--count] = VoltTackle; + actual[--count] = VoltTackle; if (count == 0) { @@ -46,11 +48,11 @@ namespace PKHeX.Core } if (!valid) - CleanResult(value.Actual, value.Possible); + CleanResult(actual, possible); return value.Actual; } - private static void CleanResult(EggSource5[] valueActual, byte[] valuePossible) + private static void CleanResult(EggSource5[] valueActual, Span valuePossible) { for (int i = 0; i < valueActual.Length; i++) { diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs index 35d31060d..25b24e53e 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs @@ -13,9 +13,9 @@ namespace PKHeX.Core { private const int level = 1; - public static EggSource6[] Validate(int generation, int species, int form, GameVersion version, int[] moves, out bool valid) + public static EggSource6[] Validate(int generation, int species, int form, GameVersion version, ReadOnlySpan moves, out bool valid) { - var count = Array.IndexOf(moves, 0); + var count = moves.IndexOf(0); if (count == 0) { valid = false; // empty moveset @@ -30,9 +30,11 @@ namespace PKHeX.Core var learnset = learn[index]; var egg = MoveEgg.GetEggMoves(generation, species, form, version); - var value = new BreedInfo(count, learnset, moves, level); + var actual = new EggSource6[count]; + Span possible = stackalloc byte[count]; + var value = new BreedInfo(actual, possible, learnset, moves, level); if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle) - value.Actual[--count] = VoltTackle; + actual[--count] = VoltTackle; if (count == 0) { @@ -46,11 +48,11 @@ namespace PKHeX.Core } if (!valid) - CleanResult(value.Actual, value.Possible); + CleanResult(actual, possible); return value.Actual; } - private static void CleanResult(EggSource6[] valueActual, byte[] valuePossible) + private static void CleanResult(EggSource6[] valueActual, Span valuePossible) { for (int i = 0; i < valueActual.Length; i++) {