2012-02-20 2 views
5

मुझे आश्चर्य है कि निम्न स्निपेट अपेक्षित परिणाम क्यों नहीं देता है? यह बहुत छोटा यादृच्छिक सरणी नहीं है और इसके लिए 3 अलग-अलग तरीकों का उपयोग करता है। मैं के रूप में तो बाहर आने के लिए गति उम्मीद कर रहा था:.NET 4.0 में Array.Sort() के साथ क्या हुआ? TrySZSort() चला गया है?

  1. Array.Sort() - सबसे तेजी से देशी TrySZSort फ़ंक्शन का उपयोग करके के रूप में मैं .NET 2.0
  2. से याद करते हैं कस्टम comparer वर्ग
  3. का उपयोग करके प्रकार अवरोही
  4. लैम्ब्डा अभिव्यक्ति क्रम।

कोड:

ascending took: 514 ms 
descending took: 537 ms 
desc lambda took: 915 ms 
ascending took: 511 ms 
descending took: 492 ms 
desc lambda took: 923 ms 
ascending took: 511 ms 
descending took: 483 ms 
desc lambda took: 912 ms 
ascending took: 511 ms 
descending took: 485 ms 
desc lambda took: 914 ms 
ascending took: 518 ms 
descending took: 485 ms 
desc lambda took: 924 ms 
... a.s.o. ... 

तो, लैम्ब्डा वास्तव में धीमी है:

class DescComparer : IComparer<double> { 
    // simple comparison 
    // (yes, its not exactly correct ...) 
    public int Compare(double x, double y) { 
     return (x > y) ? -1 : 1; 
    } 
} 
static void Main(string[] args) { 
    Stopwatch sw = new Stopwatch(); 
    Random rand = new Random(); 
    DescComparer comparer = new DescComparer(); 
    double[] a = new double[1000000]; 
    for (int r = 0; r < 20; r++) { 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort(a); 
     sw.Stop(); 
     Console.WriteLine("ascending took: {0} ms ", sw.ElapsedMilliseconds); 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort<double>(a, comparer); 
     sw.Stop(); 
     Console.WriteLine("descending took: {0} ms ", sw.ElapsedMilliseconds); 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort<double>(a, (x,y) => -x.CompareTo(y)); 
     sw.Stop(); 
     Console.WriteLine("desc lambda took: {0} ms ", sw.ElapsedMilliseconds); 

    } 
    Console.Read(); 
} 

लेकिन अजीब, यह निम्न देता है। लेकिन कैसे आता है, सादा आरोही Array.Sort अब और तेज नहीं है? क्या यह है, क्योंकि Array.Sort (टी [], तुलनात्मक) में सुधार किया गया है या TrySZSort को हटा दिया गया है? या किसी को याद किया था?

(रिलीज बिल्ड, कोई डीबग नहीं, कोई प्रतिबिंबक अभी उपलब्ध नहीं है;)) धन्यवाद!

अद्यतन: @ रीड कॉपसी द्वारा संकेत के अनुसार, लैम्ब्डा अभिव्यक्ति उचित नहीं है। मैंने तुलनात्मक रूप से इसे बदलने की कोशिश की। गति बढ़ गई। एएससी/लैम्ब्डा 55% -> 75% से चला गया। तो यह अभी भी काफी धीमी है।

+1

मैं प्रदर्शन परिणाम की व्याख्या नहीं कर सकते हैं, लेकिन परावर्तक को देख से, TrySZSort समाप्त नहीं हुई है, और दोनों 'Sort' और के लिए कहा जाता है' क्रमबद्ध 'विधियों, लेकिन केवल जब तुलनात्मक शून्य या डिफ़ॉल्ट है। –

+0

@ मेटा-नाइट एचएम। दिलचस्प! तो ऐसा प्रतीत होता है, प्रबंधित पक्ष थोड़ा पकड़ लिया। बताने के लिए धन्यवाद! –

+1

हां, Array.Sort() .NET 4 में फिर से लिखा गया था। कई सॉर्टर्स हैं।जब आप तुलनात्मक दुर्व्यवहार करते हैं तो आपको एक अंतहीन पाश में फंस नहीं होगा। संदर्भ स्रोत से उपलब्ध टिप्पणी स्रोत कोड को देखकर इसका पीछा करें। –

उत्तर

5

तो, लैम्ब्डा वास्तव में सबसे धीमा है। लेकिन कैसे आता है, सादा आरोही Array.Sort अब और तेज नहीं है? क्या यह है, क्योंकि Array.Sort (टी [], तुलनात्मक) में सुधार किया गया है या TrySZSort को हटा दिया गया है? या किसी को याद किया था?

ठीक है, यहां दो मुद्दे हैं। सबसे पहले, यह वास्तव में अपने निर्माण और सिस्टम पर निर्भर करता है -

अपने सिस्टम पर, 64 में, Array.Sort() सबसे तेजी से एक महत्वपूर्ण मात्रा से है:

ascending took: 192 ms 
descending took: 248 ms 
desc lambda took: 326 ms 
ascending took: 194 ms 
descending took: 247 ms 
desc lambda took: 326 ms 

86 पर, चीजों को थोड़ा अलग हैं - लेकिन जैसा कि आप दिखा रहे हैं उतना ही महत्व नहीं:

ascending took: 235 ms 
descending took: 223 ms 
desc lambda took: 325 ms 
ascending took: 234 ms 
descending took: 222 ms 
desc lambda took: 325 ms 

क्या आपके पास इन समयों पर चलने पर दृश्य स्टूडियो होस्ट संलग्न था? यदि आप वीएस के भीतर भागते हैं तो भी एक रिलीज बिल्ड नाटकीय रूप से धीमा होगा (यानी: डिफ़ॉल्ट रूप से Ctrl + F5 के बजाय F5)।


यह भी ध्यान दें कि लैम्बडा के संबंध में आपका परीक्षण पूरी तरह से उचित नहीं है। आप परीक्षण के लिए एक ही तंत्र है, जो होगा उपयोग करना चाहिए:

Array.Sort<double>(a, (x, y) => (x > y) ? -1 : 1); 
+0

दाएं। लैम्ब्डा (एक्स 86) में अंतर कम महत्वपूर्ण है। लेकिन लैम्बडा के बिना गति अनुपात asc/desc के बारे में हैं: 5%। –

संबंधित मुद्दे