Tôi đã làm một số thử nghiệm hiệu suất, chủ yếu là vì vậy tôi có thể hiểu sự khác biệt giữa các trình vòng lặp và đơn giản cho các vòng lặp. Là một phần của điều này, tôi đã tạo ra một bộ kiểm tra đơn giản và sau đó hoàn toàn ngạc nhiên bởi kết quả. Đối với một số phương pháp, 64 bit nhanh hơn gần 10 lần so với 32 bit.Tại sao điều này nhanh hơn trên 64 bit so với 32 bit?
Điều tôi đang tìm kiếm là một số giải thích cho lý do tại sao điều này xảy ra.
[Câu trả lời dưới đây nêu rõ điều này là do số học 64 bit trong ứng dụng 32 bit. Thay đổi độ dài để ints cho kết quả hoạt động tốt trên các hệ thống 32 bit và 64 bit.]
Dưới đây là 3 phương pháp được đề cập.
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;
}
Tôi có một khai thác thử nghiệm đơn giản mà các xét nghiệm này
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);
}
Khi tôi chạy này, tôi nhận được kết quả như sau:
32 bit:
For: 00:00:00.0006080 For2: 00:00:00.0005694 Iter: 00:00:00.0001717
64 chút
For: 00:00:00.0007421 For2: 00:00:00.0000814 Iter: 00:00:00.0000818
Những điều tôi đọc từ đây là sử dụng LongLength chậm. Nếu tôi sử dụng array.Length, hiệu suất cho vòng lặp đầu tiên là khá tốt trong 64 bit, nhưng không phải 32 bit.
Điều khác tôi đọc từ việc này là lặp qua một mảng có hiệu quả như vòng lặp for, và mã này sạch hơn và dễ đọc hơn!
Điều tôi cũng thấy thú vị là rõ ràng trình biên dịch JIT không tối ưu hóa việc truy cập mảng.LongLength. – newgre