Наилучшим подходом с точки зрения производительности является использование одного или двух массивов. Скопируйте список в массив, выполните операции с массивом, а затем создайте новый список из массива. Доступ к элементу массива быстрее, чем доступ к элементу списка, и преобразования между List<T>
и T[]
могут использовать операцию быстрого «массового копирования», которая позволяет избежать накладных расходов, связанных с доступом к отдельным элементам.
Например, предположим, что у вас есть List<string>
и вы хотите, чтобы за каждой строкой в списке, начинающейся с T
, следовал элемент «Boo», в то время как каждая строка, начинающаяся с «U», удаляется полностью. Оптимальный подход, вероятно, будет выглядеть примерно так:
int srcPtr,destPtr;
string[] arr;
srcPtr = theList.Count;
arr = new string[srcPtr*2];
theList.CopyTo(arr, theList.Count); // Copy into second half of the array
destPtr = 0;
for (; srcPtr < arr.Length; srcPtr++)
{
string st = arr[srcPtr];
char ch = (st ?? "!")[0]; // Get first character of string, or "!" if empty
if (ch != 'U')
arr[destPtr++] = st;
if (ch == 'T')
arr[destPtr++] = "Boo";
}
if (destPtr > arr.Length/2) // More than half of dest. array is used
{
theList = new List<String>(arr); // Adds extra elements
if (destPtr != arr.Length)
theList.RemoveRange(destPtr, arr.Length-destPtr); // Chop to proper length
}
else
{
Array.Resize(ref arr, destPtr);
theList = new List<String>(arr); // Adds extra elements
}
Было бы полезно, если бы List<T>
предоставил метод для построения списка из части массива, но я не знаю ни одного эффективного метода для этого. Тем не менее, операции над массивами довольно быстрые. Следует отметить тот факт, что добавление и удаление элементов из списка не требует «проталкивания» вокруг других элементов; каждый элемент записывается непосредственно в соответствующее место в массиве.