Суть в том, что List<T>.Sort()
выполняет сортировку на месте.Если ваш список открыт для внешнего кода, он всегда будет представлять один и тот же объект для этого кода.Это важно, если список хранится в поле с помощью кода вне класса контейнера.Если вы сортируете с OrderBy()
, вы будете каждый раз получать новое перечисление, заменяя предыдущее items
.Любой ранее сохраненный список не будет отображать текущее состояние вашего класса.
Учитывая производительность, OrderBy
придется перебирать весь список для сортировки элементов.Затем вы вызовете ToList()
, чтобы создать новый список из этого перечисления, повторяя этот список во второй раз.Кроме того, поскольку это перечисление, List будет использовать алгоритм удвоения, увеличивая его размер до тех пор, пока в него не поместится каждый элемент.В случае большого списка это может быть довольно много выделений и копирование памяти.Я ожидаю, что производительность будет намного хуже, чем List<T>.Sort()
.
Редактировать: Небольшой тест:
internal class Program {
private static List<int> CreateList(int size) {
// use the same seed so that every list has the same elements
Random random = new Random(589134554);
List<int> list = new List<int>(size);
for (int i = 0; i < size; ++i)
list.Add(random.Next());
return list;
}
private static void Benchmark(int size, bool output = true) {
List<int> list1 = CreateList(size);
List<int> list2 = CreateList(size);
Stopwatch stopwatch = Stopwatch.StartNew();
list1.Sort();
stopwatch.Stop();
double elapsedSort = stopwatch.Elapsed.TotalMilliseconds;
if (output)
Console.WriteLine("List({0}).Sort(): {1}ms (100%)", size, elapsedSort);
stopwatch.Restart();
list2.OrderBy(i => i).ToList();
stopwatch.Stop();
double elapsedOrderBy = stopwatch.Elapsed.TotalMilliseconds;
if (output)
Console.WriteLine("List({0}).OrderBy(): {1}ms ({2:.00%})", size, elapsedOrderBy, elapsedOrderBy / elapsedSort);
}
internal static void Main() {
// ensure linq library is loaded and initialized
Benchmark(1000, false);
Benchmark(10);
Benchmark(100);
Benchmark(1000);
Benchmark(10000);
Benchmark(100000);
Benchmark(1000000);
Console.ReadKey();
}
}
Вывод (нормализовано в List.Sort):
List(10).Sort(): 0,0025ms (100%)
List(10).OrderBy(): 0,0157ms (628,00%)
List(100).Sort(): 0,0068ms (100%)
List(100).OrderBy(): 0,0294ms (432,35%)
List(1000).Sort(): 0,0758ms (100%)
List(1000).OrderBy(): 0,3107ms (409,89%)
List(10000).Sort(): 0,8969ms (100%)
List(10000).OrderBy(): 4,0751ms (454,35%)
List(100000).Sort(): 10,8541ms (100%)
List(100000).OrderBy(): 50,3497ms (463,88%)
List(1000000).Sort(): 124,1001ms (100%)
List(1000000).OrderBy(): 705,0707ms (568,15%)