Tôi đang cố gắng đo lường sự khác biệt của việc sử dụng a for
và a foreach
khi truy cập danh sách các kiểu giá trị và kiểu tham chiếu.
Tôi đã sử dụng lớp sau để làm hồ sơ.
public static class Benchmarker
{
public static void Profile(string description, int iterations, Action func)
{
Console.Write(description);
// Warm up
func();
Stopwatch watch = new Stopwatch();
// Clean up
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
watch.Start();
for (int i = 0; i < iterations; i++)
{
func();
}
watch.Stop();
Console.WriteLine(" average time: {0} ms", watch.Elapsed.TotalMilliseconds / iterations);
}
}
Tôi đã sử dụng double
cho loại giá trị của mình. Và tôi đã tạo 'lớp giả' này để kiểm tra các loại tham chiếu:
class DoubleWrapper
{
public double Value { get; set; }
public DoubleWrapper(double value)
{
Value = value;
}
}
Cuối cùng tôi chạy mã này và so sánh sự khác biệt về thời gian.
static void Main(string[] args)
{
int size = 1000000;
int iterationCount = 100;
var valueList = new List<double>(size);
for (int i = 0; i < size; i++)
valueList.Add(i);
var refList = new List<DoubleWrapper>(size);
for (int i = 0; i < size; i++)
refList.Add(new DoubleWrapper(i));
double dummy;
Benchmarker.Profile("valueList for: ", iterationCount, () =>
{
double result = 0;
for (int i = 0; i < valueList.Count; i++)
{
unchecked
{
var temp = valueList[i];
result *= temp;
result += temp;
result /= temp;
result -= temp;
}
}
dummy = result;
});
Benchmarker.Profile("valueList foreach: ", iterationCount, () =>
{
double result = 0;
foreach (var v in valueList)
{
var temp = v;
result *= temp;
result += temp;
result /= temp;
result -= temp;
}
dummy = result;
});
Benchmarker.Profile("refList for: ", iterationCount, () =>
{
double result = 0;
for (int i = 0; i < refList.Count; i++)
{
unchecked
{
var temp = refList[i].Value;
result *= temp;
result += temp;
result /= temp;
result -= temp;
}
}
dummy = result;
});
Benchmarker.Profile("refList foreach: ", iterationCount, () =>
{
double result = 0;
foreach (var v in refList)
{
unchecked
{
var temp = v.Value;
result *= temp;
result += temp;
result /= temp;
result -= temp;
}
}
dummy = result;
});
SafeExit();
}
Tôi đã chọn Release
và Any CPU
các tùy chọn, chạy chương trình và nhận được thời gian như sau:
valueList for: average time: 483,967938 ms
valueList foreach: average time: 477,873079 ms
refList for: average time: 490,524197 ms
refList foreach: average time: 485,659557 ms
Done!
Sau đó, tôi chọn tùy chọn Phát hành và x64, chạy chương trình và nhận được thời gian như sau:
valueList for: average time: 16,720209 ms
valueList foreach: average time: 15,953483 ms
refList for: average time: 19,381077 ms
refList foreach: average time: 18,636781 ms
Done!
Tại sao phiên bản x64 bit nhanh hơn rất nhiều? Tôi mong đợi một số khác biệt, nhưng không phải là một cái gì đó lớn như thế này.
Tôi không có quyền truy cập vào các máy tính khác. Bạn có thể vui lòng chạy nó trên máy của bạn và cho tôi biết kết quả được không? Tôi đang sử dụng Visual Studio 2015 và tôi có Intel Core i7 930.
Đây là SafeExit()
phương pháp để bạn có thể tự biên dịch / chạy:
private static void SafeExit()
{
Console.WriteLine("Done!");
Console.ReadLine();
System.Environment.Exit(1);
}
Theo yêu cầu, sử dụng double?
thay vì của tôi DoubleWrapper
:
Mọi CPU
valueList for: average time: 482,98116 ms
valueList foreach: average time: 478,837701 ms
refList for: average time: 491,075915 ms
refList foreach: average time: 483,206072 ms
Done!
x64
valueList for: average time: 16,393947 ms
valueList foreach: average time: 15,87007 ms
refList for: average time: 18,267736 ms
refList foreach: average time: 16,496038 ms
Done!
Cuối cùng nhưng không kém phần quan trọng: tạo x86
hồ sơ mang lại cho tôi kết quả sử dụng gần như giống nhauAny CPU
.