2014-10-03 12 views
5

में अज्ञात फ़ंक्शन का उपयोग करके प्रदर्शन जुर्माना मैंने देखा है कि जूलिया में अज्ञात कार्यों का उपयोग करने के साथ एक प्रदर्शन जुर्माना है। उदाहरण के लिए मेरे पास क्विकॉर्ट के दो कार्यान्वयन हैं (जूलिया वितरण में माइक्रो प्रदर्शन बेंचमार्क से लिया गया)। आरोही क्रम में पहले प्रकारजूलिया

function qsort!(a,lo,hi) 
    i, j = lo, hi 
    while i < hi 
     pivot = a[(lo+hi)>>>1] 
     while i <= j 
      while a[i] < pivot; i += 1; end 
      while pivot < a[j]; j -= 1; end 
      if i <= j 
       a[i], a[j] = a[j], a[i] 
       i, j = i+1, j-1 
      end 
     end 
     if lo < j; qsort!(a,lo,j); end 
     lo, j = i, hi 
    end 
    return a 
end 

दूसरा लेता है एक अतिरिक्त पैरामीटर: को उस अज्ञात फ़ंक्शन अधिक विदेशी प्रकार

function qsort_generic!(a,lo,hi,op=(x,y)->x<y) 
    i, j = lo, hi 
    while i < hi 
     pivot = a[(lo+hi)>>>1] 
     while i <= j 
      while op(a[i], pivot); i += 1; end 
      while op(pivot, a[j]); j -= 1; end 
      if i <= j 
       a[i], a[j] = a[j], a[i] 
       i, j = i+1, j-1 
      end 
     end 
     if lo < j; qsort_generic!(a,lo,j,op); end 
     lo, j = i, hi 
    end 
    return a 
end 

वहाँ एक है के लिए बढ़ते या घटते क्रमबद्ध या तुलना निर्दिष्ट करने के लिए इस्तेमाल किया जा सकता डिफ़ॉल्ट संस्करण के साथ int64 के सरणी को सॉर्ट करते समय महत्वपूर्ण प्रदर्शन जुर्माना, तीव्रता के क्रम का क्रम तेजी से। यहाँ सेकंड में लंबाई एन के एरे छँटाई के लिए समय है:

N  qsort_generic qsort 
2048 0.00125   0.00018 
4096 0.00278   0.00029 
8192 0.00615   0.00061 
16384 0.01184   0.00119 
32768 0.04482   0.00247 
65536 0.07773   0.00490 

सवाल है: संकलक में सीमाओं उस समय में बाहर इस्त्री किया जाएगा करने के लिए इस वजह से है, या वहाँ functors पारित करने के लिए एक रास्ता है मुहावरेदार/अनाम कार्य जो इस तरह के मामलों में इस्तेमाल किया जाना चाहिए?

अद्यतन उत्तर से ऐसा लगता है कि यह कुछ ऐसा है जो संकलक में तय किया जाएगा।

इसी समय, दो सुझाव दिए गए थे। दोनों दृष्टिकोण काफी सरल हैं, हालांकि वे सी ++ (हालांकि अजीब के समान पैमाने पर नहीं) में उपयोग करने के लिए जॉगरी-पोकर की तरह महसूस करना शुरू कर देते हैं।

पहला @ टोवो हेनिंगसन द्वारा सुझाए गए फास्टएन पैकेज है। मैंने इस दृष्टिकोण की कोशिश नहीं की, लेकिन यह अच्छा लग रहा है।

मैंने @ सिमोनस्टार द्वारा सुझाई गई दूसरी विधि को आजमाया, जिसने मुझे गैर-जेनेरिक qsort के बराबर प्रदर्शन दिया! कार्यान्वयन:

abstract OrderingOp 
immutable AscendingOp<:OrderingOp end 
immutable DescendingOp<:OrderingOp end 
evaluate(::AscendingOp, x, y) = x<y 
evaluate(::DescendingOp, x, y) = x>y 

function qsort_generic!(a,lo,hi,op=AscendingOp()) 
    i, j = lo, hi 
    while i < hi 
     pivot = a[(lo+hi)>>>1] 
     while i <= j 
      while evaluate(op, a[i], pivot); i += 1; end 
      while evaluate(op, pivot, a[j]); j -= 1; end 
      if i <= j 
       a[i], a[j] = a[j], a[i] 
       i, j = i+1, j-1 
      end 
     end 
     if lo < j; qsort_generic!(a,lo,j,op); end 
     lo, j = i, hi 
    end 
    return a 
end 

सहायता के लिए सभी को धन्यवाद।

उत्तर

5

जैसा कि अन्य ने ध्यान दिया है, आपके द्वारा लिखा गया कोड idiomatic जूलिया है और किसी दिन तेजी से होगा, लेकिन संकलक अभी तक काफी नहीं है। FastAnonymous का उपयोग करने के अलावा, दूसरा विकल्प अज्ञात कार्यों के बजाय प्रकारों को पास करना है। इस पैटर्न के लिए, आप किसी भी फ़ील्ड और विधि के साथ एक अपरिवर्तनीय परिभाषित करते हैं (चलिए इसे evaluate कहते हैं) जो प्रकार और कुछ तर्कों का एक उदाहरण स्वीकार करता है। आपका सॉर्टिंग फ़ंक्शन एक फ़ंक्शन के बजाय op ऑब्जेक्ट स्वीकार करेगा और op(x, y) के बजाय evaluate(op, x, y) पर कॉल करेगा। चूंकि फ़ंक्शंस उनके इनपुट प्रकारों पर विशिष्ट होते हैं, इसलिए अबास्ट्रक्शन के लिए कोई रनटाइम ओवरहेड नहीं होता है। यह मानक पुस्तकालय में reductions और specification of sort order के साथ-साथ NumericExtensions का आधार है।

उदाहरण के लिए:

immutable AscendingSort; end 
evaluate(::AscendingSort, x, y) = x < y 

function qsort_generic!(a,lo,hi,op=AscendingSort()) 
    i, j = lo, hi 
    while i < hi 
     pivot = a[(lo+hi)>>>1] 
     while i <= j 
      while evaluate(op, a[i], pivot); i += 1; end 
      while evaluate(op, pivot, a[j]); j -= 1; end 
      if i <= j 
       a[i], a[j] = a[j], a[i] 
       i, j = i+1, j-1 
      end 
     end 
     if lo < j; qsort_generic!(a,lo,j,op); end 
     lo, j = i, hi 
    end 
    return a 
end 
9

यह एक समस्या है और आने वाले प्रकार के सिस्टम ओवरहाल के साथ तय की जाएगी।

अद्यतन: अब यह जूलिया के 0.5 संस्करण में तय किया गया है।

+3

मेरे लिए ओपी के सवाल का एक बहुत सीधा जवाब की तरह लग रहा। निश्चित रूप से प्रश्न की आलोचना और स्पष्टीकरण के लिए अनुरोध की तरह दिखता नहीं है। –

+0

धन्यवाद स्टीफन। यह जानकर अच्छा लगा कि ऐसा कोई कारण नहीं है कि इस तरह के अज्ञात कार्य "छोटी चाल" का उपयोग किए बिना तेज़ नहीं हो सकते हैं। – bcumming

5

हां, यह संकलक में सीमाओं के कारण है, और इसे ठीक करने की योजना है, उदाहरण के लिए देखें। यह issue। इस बीच, FastAnonymous पैकेज एक कामकाज प्रदान कर सकता है।

जिस तरह से आपने इसे किया है वह बहुत मूर्खतापूर्ण दिखता है, दुर्भाग्य से कोई जादू चाल नहीं है जिसे आप याद कर रहे हैं (संभवतः फास्टएनामी पैकेज को छोड़कर)।

+0

धन्यवाद @ टोविओ, यह जानना अच्छा है कि यह कुछ ऐसा है जो तय किया जाएगा। मैं सोच रहा था कि समस्या को ठीक करने के लिए किस तरह के मेटाप्रोग्रामिंग जादू का उपयोग किया जा सकता है, और ऐसा लगता है कि फास्टएनामीट उस प्रश्न का उत्तर है। – bcumming