Реализация списка <T> .AddRange неоптимальная

Профилирование моего приложения на C # показало, что вList<T>.AddRange, Использование Reflector для просмотра кода в этом методе показало, что он вызываетList<T>.InsertRange который реализован как таковой:

public void InsertRange(int index, IEnumerable<T> collection)
{
    if (collection == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
    }
    if (index > this._size)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
    }
    ICollection<T> is2 = collection as ICollection<T>;
    if (is2 != null)
    {
        int count = is2.Count;
        if (count > 0)
        {
            this.EnsureCapacity(this._size + count);
            if (index < this._size)
            {
                Array.Copy(this._items, index, this._items, index + count, this._size - index);
            }
            if (this == is2)
            {
                Array.Copy(this._items, 0, this._items, index, index);
                Array.Copy(this._items, (int) (index + count), this._items, (int) (index * 2), (int) (this._size - index));
            }
            else
            {
                T[] array = new T[count];          // (*)
                is2.CopyTo(array, 0);              // (*)
                array.CopyTo(this._items, index);  // (*)
            }
            this._size += count;
        }
    }
    else
    {
        using (IEnumerator<T> enumerator = collection.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                this.Insert(index++, enumerator.Current);
            }
        }
    }
    this._version++;
}

private T[] _items;

Можно утверждать, что простота интерфейса (только с одной перегрузкой InsertRange) оправдывает снижение производительности при проверке и приведении типов во время выполнения. Но что может быть причиной трех строк, которые я указал(*) ? Я думаю, что это может быть переписано для более быстрой альтернативы:

is2.CopyTo(this._items, index);

Видите ли вы причину не использовать эту более простую и, очевидно, более быструю альтернативу?

Редактировать:

Спасибо за ответы. Таким образом, общее мнение заключается в том, что это защитная мера против набора ввода, реализующего CopyTo дефектным / злонамеренным образом. Мне кажется излишним постоянно платить цену: 1) проверка типа во время выполнения 2) динамическое выделение временного массива 3) двойная операция копирования, когда все это можно было бы сохранить, определив 2 или несколько дополнительных перегрузок InsertRange один получаяIEnumerable как сейчас, второй получаяList<T>Третье получениеT[], Последние два могли быть реализованы так, чтобы бегать вдвое быстрее, чем в текущем случае.

Изменить 2:

Я реализовал класс FastList, идентичный List, за исключением того, что он также обеспечивает перегрузку AddRange, которая принимает аргумент T []. Эта перегрузка не требует динамической проверки типов и двойного копирования элементов. Я сделал профиль этого FastList.AddRange для List.AddRange, добавив 4-байтовые массивы 1000 раз в список, который изначально был emtpy. Моя реализация превосходит скорость стандартного List.AddRange с коэффициентом 9 (девять!). List.AddRange занимает около 5% времени выполнения в одном из важных сценариев использования нашего приложения. Замена List классом, обеспечивающим более быстрый AddRange, может улучшить время выполнения приложения на 4%.

Ответы на вопрос(3)

Ваш ответ на вопрос