Logging based on https://twitter.com/AntaoAlmada/status/1235979836289675266?s=20.
When creating a List<T> from an IEnumerable<T> (where the enumerable is not an ICollection<T>), the implementation is quite inefficient as it is basically foreach (item in enumeration) { Add(item); }. For large enumerations, this results in the underlying arrays being created, resized, copied numerous times. On the other hand, Enumerable.ToArray() internally uses LargeArrayBuilder which is a bit more efficient for constructing an array of unknown size. This looks to be because it effectively tracks the individual fragmented arrays and combines them together at the end (thus avoiding much of the repeated copying for very large arrays).
This can result in significant perf differences:

It may be worthwhile investigating if List<T>(IEnumerable<T>) can be improved similarly, naively we could possibly just have it be _items = collection.ToArray().
Logging based on https://twitter.com/AntaoAlmada/status/1235979836289675266?s=20.
When creating a
List<T>from anIEnumerable<T>(where the enumerable is not anICollection<T>), the implementation is quite inefficient as it is basicallyforeach (item in enumeration) { Add(item); }. For large enumerations, this results in the underlying arrays being created, resized, copied numerous times. On the other hand,Enumerable.ToArray()internally usesLargeArrayBuilderwhich is a bit more efficient for constructing an array of unknown size. This looks to be because it effectively tracks the individual fragmented arrays and combines them together at the end (thus avoiding much of the repeated copying for very large arrays).This can result in significant perf differences:

It may be worthwhile investigating if
List<T>(IEnumerable<T>)can be improved similarly, naively we could possibly just have it be_items = collection.ToArray().