मैं मूल्य प्रकारों और संदर्भ प्रकारों की सूचियों तक पहुँचने के दौरान for
और ए का उपयोग करने के अंतर को मापने की कोशिश कर रहा था foreach
।
मैंने प्रोफाइलिंग करने के लिए निम्न वर्ग का उपयोग किया।
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);
}
}
मैंने double
अपने मूल्य प्रकार के लिए उपयोग किया । और मैंने इस 'नकली वर्ग' को संदर्भ प्रकारों का परीक्षण करने के लिए बनाया है:
class DoubleWrapper
{
public double Value { get; set; }
public DoubleWrapper(double value)
{
Value = value;
}
}
अंत में मैंने इस कोड को चलाया और समय के अंतर की तुलना की।
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();
}
मैंने चयन किया Release
और Any CPU
विकल्प दिए, कार्यक्रम चलाया और निम्नलिखित समय मिला:
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!
फिर मैंने रिलीज़ और x64 विकल्प चुने, कार्यक्रम चलाया और निम्नलिखित बार मिला:
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!
X64 बिट संस्करण इतना तेज क्यों है? मुझे कुछ अंतर की उम्मीद थी, लेकिन इस बड़े से कुछ नहीं।
मेरे पास अन्य कंप्यूटरों तक पहुंच नहीं है। क्या आप कृपया इसे अपनी मशीनों पर चला सकते हैं और मुझे परिणाम बता सकते हैं? मैं विजुअल स्टूडियो 2015 का उपयोग कर रहा हूं और मेरे पास इंटेल कोर i7 930 है।
यहाँ SafeExit()
विधि है, ताकि आप स्वयं को संकलित / चला सकें:
private static void SafeExit()
{
Console.WriteLine("Done!");
Console.ReadLine();
System.Environment.Exit(1);
}
अनुरोध के अनुसार, double?
मेरे बजाय का उपयोग कर DoubleWrapper
:
कोई सीपीयू
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!
64
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!
अंतिम लेकिन कम से कम नहीं: एक x86
प्रोफ़ाइल बनाने से मुझे उपयोग करने के लगभग समान परिणाम मिलते हैंAny CPU
।