You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Avoid intermediate array allocation when the collection is first created (#11799)
In Framework, `List<T>.AddRange()` has a specialization for
`ICollection<T>` where it allocates an intermediate array to copy the
contents of the collection. It then copies the contents of the
intermediate array to the inner list.
public void AddRange(IEnumerable<T> collection)
{
InsertRange(_size, collection);
}
...
public void InsertRange(int index, IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
if ((uint)index > (uint)_size)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index,
ExceptionResource.ArgumentOutOfRange_Index);
}
if (collection is ICollection<T> { Count: var count } collection2)
{
if (count > 0)
{
EnsureCapacity(_size + count);
if (index < _size)
{
Array.Copy(_items, index, _items, index + count, _size - index);
}
if (this == collection2)
{
Array.Copy(_items, 0, _items, index, index);
Array.Copy(_items, index + count, _items, index * 2, _size - index);
}
else
{
T[] array = new T[count]; // Intermediate array allocation here
collection2.CopyTo(array, 0); // copying to the intermediate array
array.CopyTo(_items, index); // copying from the intermediate array to
the inner list
}
_size += count;
}
}
else
{
using IEnumerator<T> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
Insert(index++, enumerator.Current);
}
}
_version++;
}
The constructor just allocates the internal array and does the copy once
public List(IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
if (collection is ICollection<T> { Count: var count } collection2)
{
if (count == 0)
{
_items = _emptyArray;
return;
}
_items = new T[count];
collection2.CopyTo(_items, 0);
_size = count;
return;
}
_size = 0;
_items = _emptyArray;
foreach (T item in collection)
{
Add(item);
}
}
Fixes #
### Context
### Changes Made
### Testing
### Notes
0 commit comments