我一直在进行一些性能测试,主要是为了了解迭代器和简单 for 循环之间的区别。作为其中的一部分,我创建了一组简单的测试,然后对结果感到非常惊讶。对于某些方法,64 位比 32 位快近 10 倍。
我正在寻找的是对为什么会发生这种情况的一些解释。
[下面的答案指出这是由于 32 位应用程序中的 64 位算术造成的。将长整型更改为整数会在 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 bit:
For: 00:00:00.0006080
For2: 00:00:00.0005694
Iter: 00:00:00.0001717
64 bit
For: 00:00:00.0007421
For2: 00:00:00.0000814
Iter: 00:00:00.0000818
我从中读到的内容是使用 LongLength 很慢。如果我使用 array.Length,第一个 for 循环的性能在 64 位中相当不错,但在 32 位中则不然。
我从中读到的另一件事是,迭代数组与 for 循环一样高效,并且代码更干净、更易于阅读!