Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 5, 2025

  • Add AddRange method to ArrayBuilder<T> in /src/libraries/Common/src/System/Collections/Generic/ArrayBuilder.cs
  • Refactor Directory.cs to use ArrayBuilder<T> with AddRange instead of new List<T>(enumerable).ToArray()
  • Refactor DirectoryInfo.cs to use ArrayBuilder<T> with AddRange instead of new List<T>(enumerable).ToArray()
  • Refactor Timer.cs to use ArrayBuilder<T> with AddRange instead of new List<T>(enumerable).ToArray()
  • Add tests for ArrayBuilder<T>.AddRange method
  • Optimize AddRange to pre-allocate for ICollection<T> inputs
  • Add AddRange method to NativeAOT's ArrayBuilder<T> in /src/coreclr/tools/Common/System/Collections/Generic/ArrayBuilder.cs
  • Add tests specifically for ICollection<T> optimization:
    • AddRange_ICollection_PreallocatesCapacity - verifies capacity is pre-allocated for ICollection inputs
    • AddRange_ICollection_EmptyCollection - verifies empty ICollection works correctly
    • AddRange_ICollection_AfterExistingItems - verifies ICollection optimization works when items already exist
    • AddRange_NonICollection_GrowsIncrementally - verifies non-ICollection path grows incrementally
  • Build and test to verify changes work correctly
Original prompt

There are a few locations in src/libraries/System.Private.CoreLib/src/System/IO/Directory.cs src/System/IO/DirectoryInfo.cs, and src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs that have code of the pattern new List<concretetype>(enumerableData).ToArray(). They do this because they're in System.Private.Corelib, and don't have access to LINQ's ToArray method. However, these locations can be improved by using System.Collections.Generic.ArrayBuilder<T>, which is in corelib and can potentially avoid intermediate allocations. Refactor these locations to use ArrayBuilder<T>, and do it by adding an AddRange helper to ArrayBuilder to encapsulate the enumeration loop and keep callsites fairly simple. You don't need to search for any instances of this code pattern outside the files I've listed; they exist, but they're all tests and don't really need to be adjusted now.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Refactor code to use ArrayBuilder for better performance Add ArrayBuilder.AddRange and use it instead of List.ToArray pattern Dec 5, 2025
Copilot AI requested a review from 333fred December 5, 2025 03:00
Copilot finished work on behalf of 333fred December 5, 2025 03:00
Copilot AI requested a review from 333fred December 5, 2025 03:35
Copilot finished work on behalf of 333fred December 5, 2025 03:35
@333fred 333fred marked this pull request as ready for review December 5, 2025 04:14
Copilot AI review requested due to automatic review settings December 5, 2025 04:14
Copilot finished reviewing on behalf of 333fred December 5, 2025 04:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an AddRange method to ArrayBuilder<T> to improve performance in locations that previously used the new List<T>(enumerable).ToArray() pattern. The implementation optimizes for ICollection<T> inputs by pre-allocating capacity, while falling back to incremental growth for general IEnumerable<T> inputs.

Key changes:

  • Added AddRange(IEnumerable<T>) method to both Common and NativeAOT ArrayBuilder<T> implementations with ICollection<T> optimization
  • Refactored I/O methods in Directory.cs, DirectoryInfo.cs, and Timer.cs to use ArrayBuilder<T>.AddRange() instead of List<T>.ToArray()
  • Added comprehensive test coverage including tests for the ICollection optimization path, empty collections, and incremental growth

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/libraries/Common/src/System/Collections/Generic/ArrayBuilder.cs Adds AddRange method with ICollection optimization for pre-allocating capacity
src/coreclr/tools/Common/System/Collections/Generic/ArrayBuilder.cs Adds AddRange method to NativeAOT's ArrayBuilder with same optimization
src/libraries/System.Private.CoreLib/src/System/IO/Directory.cs Refactors three methods (GetFiles, GetDirectories, GetFileSystemEntries) to use ArrayBuilder.AddRange instead of List.ToArray pattern
src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs Refactors three methods (GetFiles, GetFileSystemInfos, GetDirectories) to use ArrayBuilder.AddRange instead of List.ToArray pattern
src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs Refactors debugger proxy property to use ArrayBuilder.AddRange instead of List.ToArray pattern
src/libraries/Common/tests/Tests/System/Collections/Generic/ArrayBuilderTests.cs Adds comprehensive test coverage for AddRange including ICollection optimization, empty collections, and non-ICollection paths

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants