При использовании метода расширения IEnumerable<T>
Count()
массив по меньшей мере в два раза медленнее, чем список.
Function Count()
List<int> 2,299
int[] 6,903
Откуда произошла разница?
Я понимаю, что оба вызова свойства Count
ICollection
:
Если тип источника реализует ICollection, эта реализация используется для получения количества элементов. В противном случае этот метод определяет счетчик.
Для списка он возвращает List<T>.Count
и для массива Array.Length
. Более того, Array.Length
предполагается быстрее, чем List<T>.Count
.
Benchmark:
class Program
{
public const long Iterations = (long)1e8;
static void Main()
{
var list = new List<int>(){1};
var array = new int[1];
array[0] = 1;
var results = new Dictionary<string, TimeSpan>();
results.Add("List<int>", Benchmark(list, Iterations));
results.Add("int[]", Benchmark(array, Iterations));
Console.WriteLine("Function".PadRight(30) + "Count()");
foreach (var result in results)
{
Console.WriteLine("{0}{1}", result.Key.PadRight(30), Math.Round(result.Value.TotalSeconds, 3));
}
Console.ReadLine();
}
public static TimeSpan Benchmark(IEnumerable<int> source, long iterations)
{
var countWatch = new Stopwatch();
countWatch.Start();
for (long i = 0; i < iterations; i++) source.Count();
countWatch.Stop();
return countWatch.Elapsed;
}
}
Edit:
leppie и ответы Knaģis довольно удивительны, но я хочу добавить замечание.
Как сказал Джон Скит:
Существует фактически два эквивалентных блока, просто тестирование для различные типы интерфейсов сбора данных и использование того, что находит сначала (если есть). Я не знаю, проверяются ли тесты .NET для ICollection или ICollection <T> сначала - я мог бы проверить это путем внедрения оба интерфейса, но, разумеется, но это, вероятно, излишнее. Это не имеет большого значения для хорошие коллекции, отличные от небольшой разницы в производительности - Сначала мы хотим протестировать "наиболее вероятный" интерфейс, который, я считаю, является общим.
Возможно, наиболее вероятно, что общий вариант может произойти, но если вы инвертируете два, то есть вызовите не общий набор перед родовым, Array.Count() станет немного быстрее, чем List.Count(). С другой стороны, для версии List нестандартная версия медленнее.
Полезно знать, хочет ли кто-нибудь позвонить Count()
в цикл итераций 1e8!
Function ICollection<T> Cast ICollection Cast
List 1,268 1,738
Array 5,925 1,683