Я выполнял некоторые тесты производительности, в основном, поэтому я могу понять разницу между итераторами и простыми для циклов. В рамках этого я создал простой набор тестов и был полностью удивлен результатами. Для некоторых методов бит 64 бит был почти в 10 раз быстрее, чем 32 бит.
То, что я ищу, является некоторым объяснением того, почему это происходит.
[Следующий ответ говорит, что это связано с 64-разрядной арифметикой в 32-битном приложении. Изменение longs to int приводит к хорошей производительности в 32 и 64-битных системах.]
Вот три метода, о которых идет речь.
private static long ForSumArray(long[] array)
{
var result = 0L;
for (var i = 0L; i < array.LongLength; i++)
{
result += array[i];
}
return result;
}
private static long ForSumArray2(long[] array)
{
var length = array.LongLength;
var result = 0L;
for (var i = 0L; i < length; i++)
{
result += array[i];
}
return result;
}
private static long IterSumArray(long[] array)
{
var result = 0L;
foreach (var entry in array)
{
result += entry;
}
return result;
}
У меня есть простая тестовая жгут, которая проверяет этот
var repeat = 10000;
var arrayLength = 100000;
var array = new long[arrayLength];
for (var i = 0; i < arrayLength; i++)
{
array[i] = i;
}
Console.WriteLine("For: {0}", AverageRunTime(repeat, () => ForSumArray(array)));
repeat = 100000;
Console.WriteLine("For2: {0}", AverageRunTime(repeat, () => ForSumArray2(array)));
Console.WriteLine("Iter: {0}", AverageRunTime(repeat, () => IterSumArray(array)));
private static TimeSpan AverageRunTime(int count, Action method)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
for (var i = 0; i < count; i++)
{
method();
}
stopwatch.Stop();
var average = stopwatch.Elapsed.Ticks / count;
return new TimeSpan(average);
}
Когда я запускаю их, я получаю следующие результаты:
32 бит:
For: 00:00:00.0006080 For2: 00:00:00.0005694 Iter: 00:00:00.0001717
64 бит
For: 00:00:00.0007421 For2: 00:00:00.0000814 Iter: 00:00:00.0000818
То, что я прочитал из этого, заключается в том, что использование LongLength происходит медленно. Если я использую array.Length, производительность для первого цикла цикла довольно хороша в 64-битной, но не 32-разрядной версии.
Другое, что я прочитал из этого, состоит в том, что итерация по массиву столь же эффективна, как и цикл for, а код намного чище и легче читать!