Skip to content

Grow geometrically in CollectionsMarshal.SetCount - #693

Merged
SimonCropp merged 1 commit into
mainfrom
perf/setcount-growth
Oct 12, 2026
Merged

SimonCropp merged 1 commit into
mainfrom
perf/setcount-growth

Conversation

@SimonCropp

Copy link
Copy Markdown
Owner

The CollectionsMarshal.SetCount polyfill (the recreated type below net5 in CollectionsMarshal.cs, and the extension for net5-net7 in CollectionsMarshalSetCount.cs) grew the list with list.Capacity = count. That is an exact fit, so every later call that raises the count by a little reallocates and copies the whole backing array: raising the count one at a time is quadratic.

Both copies now grow the way List<T> itself does (and the way the BCL SetCount does through List<T>.Grow): double the current capacity (4 when empty), capped at the maximum array length, and use count when doubling is not enough. Counts, contents and the default-initialised tail are unchanged; the only observable difference is Capacity, which now matches what the BCL produces for the same calls.

Measurements

net48, Release, x64, best of 3, SetCount(list, i) for i = 1..40,000 on a List<int>:

before after
141.57 ms 0.18 ms

Tests

Added to PolyfillTests_CollectionsMarshal.cs (polyfill below net8, BCL from net8):

  • SetCount_GrowKeepsItemsAndDefaultsTheRest, SetCount_GrowFromEmpty, SetCount_GrowWithinCapacity (capacity untouched when it already fits), SetCount_ShrinkThenGrow
  • SetCount_GrowsCapacityLikeList: pins the capacity sequence (exact fit when doubling is not enough, otherwise double, 4 from empty), which is the same on the BCL
  • SetCount_IncrementalGrowth: 20,000 single-step increments, checking every element survives and the capacity stays within 2x
  • SetCount_InvalidArguments

@SimonCropp SimonCropp added this to the 11.4.5 milestone Oct 12, 2026
@SimonCropp
SimonCropp merged commit 31c3fd5 into main Oct 12, 2026
5 checks passed
@SimonCropp
SimonCropp deleted the perf/setcount-growth branch October 12, 2026 12:14
This was referenced Oct 12, 2026
This was referenced Oct 14, 2026
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.

1 participant