Почему это быстрее на 64 бит, чем 32 бит?

Я провел тестирование производительности, в основном, чтобы понять разницу между итераторами и простыми циклами for. В рамках этого я создал простой набор тестов, а затем был полностью удивлен результатами. Для некоторых методов 64-битный был почти в 10 раз быстрее, чем 32-битный.

Я ищу объяснение, почему это происходит.

[Ответ ниже утверждает, что это связано с 64-битной арифметикой в 32-битном приложении. Изменение long в ints приводит к хорошей производительности на 32- и 64-битных системах.]

Вот 3 метода в вопросе.

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, производительность для первого цикла for довольно хороша в 64-битной, но не 32-битной.

Другая вещь, которую я прочитал из этого, состоит в том, что перебор массива так же эффективен, как цикл for, а код намного чище и проще для чтения!

Ответы на вопрос(5)

Ваш ответ на вопрос