Repository: dotnet/runtime
File: src/libraries/System.Private.CoreLib/src/System/Array.cs (C#)

Code before:
                    // Large arrays are rented, cheaper than to grow a List multiple times & no GC, only release
                    matchArray ??= GetMatchArray(array.Length - i);
                    matchArray[matchesFound++] = array[i];
                }
            }

            if (matchArray == null)
                return EmptyArray<T>.Value;

            if (matchArray.Length == matchesFound && sharedArrayPool == null)
                return matchArray; // If we have matched all allocated and not rented the array, we can just return it, brilliant suggestion from lechu445

            // If all were matches, we could have returned the existing array,
            // but the old code always made a new array, so it would be a breaking change
            T[] result = new T[matchesFound];
            Buffer.Memmove(ref MemoryMarshal.GetArrayDataReference(result), ref MemoryMarshal.GetArrayDataReference(matchArray), matchesFound);
            sharedArrayPool?.Return(matchArray);

            return result;

            T[] GetMatchArray(int size)
            {
                // This is about where execution time breaks even for:
                // Windows 11 (10.0.26100.6584/24H2/2024Update/HudsonValley)
                // .NET 10.0.0 (10.0.0-rc.1.25451.107, 10.0.25.45207), X64 RyuJIT x86-64-v3
                if (size >= 48)
                {
                    sharedArrayPool = ArrayPool<T>.Shared;
                    return sharedArrayPool.Rent(size);
                }

                return new T[size];
            }
        }

        public static int FindIndex<T>(T[] array, Predicate<T> match)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            return FindIndex(array, 0, array.Length, match);
        }

        public static int FindIndex<T>(T[] array, int startIndex, Predicate<T> match)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

Review comment (suggestion):
This is not a reliable measurement. The impact of GC pressure can vary with other environment factors.

The pattern we are using is to use `stackalloc` for small sizes and array pool when it's too large (>256/512)

Code after:
            foreach (T value in array)
            {
                if (match(value))
                {
                    if (foundCount >= span.Length)
                    {
                        values = new T[Math.Min((uint)span.Length * 2, (uint)array.Length)];
                        span.CopyTo(values);
                        span = values;
                    }

                    span[foundCount++] = value;
                }
            }

            return values?.Length == foundCount ? values : span[..foundCount].ToArray();
        }

        public static int FindIndex<T>(T[] array, Predicate<T> match)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            return FindIndex(array, 0, array.Length, match);
        }

        public static int FindIndex<T>(T[] array, int startIndex, Predicate<T> match)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            return FindIndex(array, startIndex, array.Length - startIndex, match);
        }

        public static int FindIndex<T>(T[] array, int startIndex, int count, Predicate<T> match)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            if (startIndex < 0 || startIndex > array.Length)
            {
                ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_IndexMustBeLessOrEqual();
            }

            if (count < 0 || startIndex > array.Length - count)