diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.cs b/src/libraries/System.Private.CoreLib/src/System/Array.cs index 5ff7790fad3ae0..15a6012bef33cd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.cs @@ -1548,15 +1548,53 @@ public static T[] FindAll(T[] array, Predicate match) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - List list = new List(); + List? heapMatches = null; // only allocate if needed + InlineArray16 stackAllocatedMatches = default; + const int InlineArrayLength = 16; + int stackAllocatedMatchesFound = 0; for (int i = 0; i < array.Length; i++) { if (match(array[i])) { - list.Add(array[i]); + if (stackAllocatedMatchesFound < InlineArrayLength) + { + stackAllocatedMatches[stackAllocatedMatchesFound++] = array[i]; + } + else + { + // Revert to the old logic, allocating and growing a List + heapMatches ??= []; + heapMatches.Add(array[i]); + } } } - return list.ToArray(); + + if (stackAllocatedMatchesFound == 0) + { + return EmptyArray.Value; + } + + int resultLength = stackAllocatedMatchesFound; + if (heapMatches != null) + { + resultLength += heapMatches.Count; + } + + T[] result = new T[resultLength]; + + int index = 0; + foreach (T stackAllocatedMatch in stackAllocatedMatches) + { + result[index++] = stackAllocatedMatch; + if (index >= stackAllocatedMatchesFound) + { + break; + } + } + + heapMatches?.CopyTo(result.AsSpan(start: InlineArrayLength)); + + return result; } public static int FindIndex(T[] array, Predicate match)