2016-06-04 22 views
7

मैं निम्नलिखित प्रविष्टि तरह एल्गोरिथ्म कार्यान्वयन है:फ़ंक्शन कॉल इतना समय क्यों लेता है?

private static void InsertionSort(List<int> array) 
{ 
    for (int i = 1; i < array.Count; ++i) 
    { 
     for (int j = i; j > 0 && array[j - 1] > array[j]; --j) 
     { 
      //swap(array, j, j-1); 

      int temp = array[j]; 
      array[j] = array[j-1]; 
      array[j-1] = temp; 
     } 
    } 
} 

private static void swap(List<int> array, int i, int j) 
{ 
    int temp = array[i]; 
    array[i] = array[j]; 
    array[j] = temp; 
} 

जब मैं swap(array, j, j-1); के साथ मेरे एल्गोरिथ्म चलाने यह बहुत अधिक समय (50000 तत्वों के लिए 2 सेकंड) अगर तुलना में मैं समारोह शरीर इनलाइन कर लेता है।

क्यों?

+1

मुझे लगता है कि रिहाई का निर्माण है? (प्रासंगिक लिंक: http://stackoverflow.com/q/15713910/11683, http://stackoverflow.com/q/473782/11683) – GSerg

+0

क्या आपको सरणी तर्क पर "ref" कहने की आवश्यकता नहीं है "स्वैप "? –

+0

मुझे नहीं लगता। यह सी # –

उत्तर

15

हाथ से विधि को रेखांकित करना गलत नहीं है, यह आवश्यक नहीं है। छोटे तरीकों को रेखांकित करना जिटर द्वारा किए गए standard optimizations में से एक है। यह हमेशा नहीं होता है, लेकिन .NET 4.6.1 पर इस नमूना कोड में x86 और x64 jitters दोनों इनलाइन स्वैप() करते हैं। और अधिक, वे दो प्रति पास स्वैप बनाने के लिए आंतरिक लूप को भी अनलॉक करते हैं, हाथ-अनुकूलन प्रोग्रामर आमतौर पर छोड़ते हैं।

एक .NET ऐप का उचित रूप से बेंचमार्क करना हमेशा सीधा-आगे नहीं होता है। बहुत आपके प्रोग्राम के रिलीज बिल्ड को चलाने के लिए महत्वपूर्ण है। और डीबगर का उपयोग करें। यद्यपि उत्तरार्द्ध को ठीक करना आसान है, उपकरण> विकल्प> डिबगिंग> सामान्य> का उपयोग करें "Jpress ऑप्टिमाइज़ेशन को दबाएं" विकल्प को अनचेक करें। इसे वापस चालू करने का कोई अच्छा कारण नहीं है।

अब आप जेनरेट किए गए मशीन कोड को भी देख सकते हैं, InsertionSort() पर ब्रेकपॉइंट सेट कर सकते हैं और जब यह डीबग> विंडोज> डिस्सेप्लर का उपयोग करता है। लोगों की आंखें खून बहती है लेकिन यह देखना आसान है कि आपको दो रेखांकित स्वैप() मिलते हैं। मैं आपको असेंबली डंप छोड़ दूंगा, बस एक नज़र डालें। और आपको माप में अंतर स्पष्ट रूप से देखना चाहिए।

यह 64 पर स्वैप() एक सूची पर 50,000 यादृच्छिक पूर्णांकों के साथ साथ 5 बार चल रहा है::

00:00:05.4447216 
00:00:05.2928558 
00:00:05.6960587 
00:00:05.2835343 
00:00:05.2809591 

एक ही परीक्षण लेकिन अब स्वैप() हाथ से inlined:

00:00:05.3015856 
00:00:05.2877402 
00:00:05.6369775 
00:00:05.2603384 
00:00:05.2616389 
यहाँ मैं क्या मिलता है

उतना ही समय लगता है जितना इसे करना चाहिए।

मैं बेपरवाह होगा परिणाम मैं List.Sort() के साथ नहीं दिखाने के लिए:

00:00:00.0075878 
00:00:00.0073398 
00:00:00.0076528 
00:00:00.0078046 
00:00:00.0066319 
+1

ओह, मैं अपने कार्यक्रम के डीबग बिल्ड चलाता हूं! अंतर क्या है? –

+0

List.Sort()। किस प्रकार का सॉर्टिंग एल्गोरिदम इसका उपयोग करता है? त्वरित प्रकार? –

+4

ठीक है, अब आप जानते हैं कि अंतर क्या है, मैंने जिन अनुकूलन से लिंक किया है, वे नहीं किए गए हैं ताकि आप विधि कॉल की लागत देख सकें। यह [आत्मनिरीक्षण क्रम] (https://en.wikipedia.org/wiki/Introsort) का उपयोग करता है। –

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