Array.Count () намного медленнее, чем List.Count ()
При использовании метода расширенияIEnumerable
Count()
, массив как минимум в два раза медленнее, чем список.
Function Count()
List 2,299
int[] 6,903
Откуда взялась разница?
Я понимаю, что оба называютCount
собственностью :ICollection
Если тип источника реализует ICollection, эта реализация используется для получения количества элементов. В противном случае этот метод определяет количество.
Для списка это возвращаетList.Count
и для массива,Array.Length
, Более того,Array.Length
должен быть быстрее, чем.List.Count
Ориентир:
class Program
{
public const long Iterations = (long)1e8;
static void Main()
{
var list = new List(){1};
var array = new int[1];
array[0] = 1;
var results = new Dictionary();
results.Add("List", 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 source, long iterations)
{
var countWatch = new Stopwatch();
countWatch.Start();
for (long i = 0; i < iterations; i++) source.Count();
countWatch.Stop();
return countWatch.Elapsed;
}
}
Редактировать:
leppie а такжесукявляется ответы довольно удивительны, но я хочу добавить замечание.
Как сказал Джон Скит:
Фактически есть два эквивалентных блока, просто тестирующих различные типы интерфейса коллекции и использующих тот, который найден первым (если есть). Я нене знает, тестирует ли реализация .NET для ICollection или ICollection <T> во-первых, я мог бы проверить это, реализовав оба интерфейса, но, конечно, возвращая разные значения для каждого, но этоСкорее всего, перебор. Это недля коллекций с хорошим поведением не имеет значения, кроме небольшой разницы в производительности - мы хотим проверитьболее вероятный" Первый интерфейс, который я считаю, является общим.
Скорее всего, универсальный может произойти, но если вы инвертируете два, то есть вызовете не универсальное приведение перед универсальным, Array.Count () станет немного быстрее, чем List.Count (). С другой стороны, неуниверсальная версия медленнее для List.
Полезно знать, если кто-то хочет позвонитьCount()
в цикле 1e8 итераций!
Function ICollection Cast ICollection Cast
List 1,268 1,738
Array 5,925 1,683