2012-06-25 10 views
11

मैं प्रदर्शन समस्याओं के कारण साइथन सीखना शुरू कर रहा हूं। यह विशेष कोड परिवहन मॉडलिंग (नियोजन के लिए) क्षेत्र में कुछ नए एल्गोरिदम लागू करने का प्रयास है।पाइथन की तुलना में साइथन में यह कोड धीमा क्यों है?

मैंने एक बहुत ही सरल कार्य शुरू करने का फैसला किया कि मैं एक बहुत (लाखों बार सैकड़ों) का उपयोग करूंगा और निश्चित रूप से प्रदर्शन में वृद्धि से लाभान्वित होगा।

मैं तीन अलग अलग तरीकों से इस समारोह को लागू किया और उन्हें 10 लाख बार प्रत्येक के लिए एक ही पैरामीटर (सरलता के लिए) के लिए परीक्षण किया:

एक cython मॉड्यूल में
  • Cython कोड। रनिंग समय: 3.35s
  • साइथन मॉड्यूल में पायथन कोड। चलने का समय: 4.88s
  • मुख्य लिपि पर पायथन कोड। चलने का समय: 2.98s

    जैसा कि आप देख सकते हैं, साइथन कोड साइथन मॉड्यूल में पायथन कोड से 45% धीमी थी और मुख्य स्क्रिप्ट पर लिखे गए कोड से 64% धीमी थी। वो कैसे संभव है? मैं गलती कहां कर रहा हूँ?

cython कोड यह है:

def BPR2(vol, cap, al, be): 
    con=al*pow(vol/cap,be) 
    return con 


def func (float volume, float capacity,float alfa,float beta): 
    cdef float congest 
    congest=alfa*pow(volume/capacity,beta) 
    return congest 

और परीक्षण के लिए स्क्रिप्ट यह है:

agora=clock() 
for i in range(10000000): 
    q=linkdelay.BPR2(10,5,0.15,4) 

agora=clock()-agora 
print agora 

agora=clock() 
for i in range(10000000): 
    q=linkdelay.func(10,5,0.15,4) 

agora=clock()-agora 
print agora 

agora=clock() 
for i in range(10000000): 
    q=0.15*pow(10/5,4) 

agora=clock()-agora 
print agora 

मैं (शक्ति) धीमी ट्रान्सेंडैंटल कार्यों जैसे मुद्दों के बारे में पता किया जा रहा हूँ, लेकिन मुझे नहीं लगता कि यह एक समस्या होनी चाहिए।

चूंकि फ़ंक्शन स्पेस पर फ़ंक्शन की तलाश करने के लिए ओवरहेड है, तो क्या यह कार्यक्षमता में मदद करेगा यदि मैंने फ़ंक्शन के लिए सरणी पास की है और सरणी वापस ले ली है? क्या मैं साइथन में लिखे गए फ़ंक्शन का उपयोग कर सरणी वापस कर सकता हूं?

संदर्भ के लिए, मैं उपयोग कर रहा हूँ: - विंडोज 7 64bits - अजगर 2.7.3 64 बिट्स - Cython 0.16 64 बिट्स - विंडोज विजुअल स्टूडियो 2008

+1

तो, यदि आप फ़ंक्शन में सरणी पास करने के बारे में सोच रहे हैं, तो संभवतः आप कोड को वेक्टरिज़ कर सकते हैं, इस मामले में आपने क्या किया है आप बस [NumPy] (http://numpy.scipy.org/) के साथ क्या करने की कोशिश कर रहे हैं? निश्चित रूप से, आपके उदाहरण में फ़ंक्शन को NumPy का उपयोग करके सरणी पर कार्यान्वित किया जा सकता है। –

+0

वैसे यह एक बेहद मामूली फ़ंक्शन है और साइथन को 'PyObject *' को एक फ्लोट में परिवर्तित करना होगा और फिर वापस नहीं है? इस तरह के एक छोटे से काम के लिए बहुत अधिक उपर की तरह लगता है। – Voo

+1

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

उत्तर

1

इस समारोह में इस तरह के रूप अनुकूलित किया जा सकता है (दोनों अजगर और cython, मध्यवर्ती चर को हटाने के तेजी से होता है):

def func(float volume, float capacity, float alfa,f loat beta): 
    return alfa * pow(volume/capacity, beta) 
+1

यह वास्तव में परिमाण की गति के वांछित क्रम की ओर बढ़ने वाला नहीं है ... –

+0

लेकिन इससे मदद मिलेगी। इसे आज़माएं और फिर देखें कि यह गति कहां रखता है। – C0deH4cker

+5

नहीं, यह नहीं होगा। यह समयपूर्व अनुकूलन के साथ समस्या का सार है। अपने प्रयासों को एल्गोरिदमिक सुधारों में रखें। –

3

परीक्षण का उपयोग किया गया था:

for i in range(10000000): 
    func(2.7,2.3,2.4,i) 

cdef float func(float v, float c, float a, float b): 
    return a * (v/c) ** b 
#=> 0.85 

cpdef float func(float v, float c, float a, float b): 
    return a * (v/c) ** b 
#=> 0.84 

def func(v,c,a,b): 
    return a * pow(v/c,b) 
#=> 3.41 

cdef float func(float v, float c, float a, float b): 
    return a * pow(v/c, b) 
#=> 2.35 

उच्चतम क्षमता के लिए आप सी में समारोह को परिभाषित करने और वापसी प्रकार स्थिर बनाने की जरूरत है:

यहाँ के परिणाम हैं।

+0

जिज्ञासा से बाहर, अगर आप libc.math cimport pow से हैं तो अंतिम 2 बेहतर हो जाएं? – mgilson

+0

अब मुझे क्रमश: 3.35 और 1.35 मिलते हैं। तो हाँ। –

+0

निश्चित रूप से बाहरी सी lib में स्थिर रिटर्न प्रकार को सेट करने में किसी भी समय की कमी कॉलिंग ओवरहेड द्वारा बौने जा रही है। आपकी सभी गति वृद्धि केवल पाइथन libs में कॉल को कम करने के लिए नीचे हैं। साथ ही, मैं उत्सुक हूं कि '**' ऑपरेटर को 'libc.math' की 'पाउ' से तेज बनाने के लिए साइथन क्या कर रहा है। कोई भी मौका आप आउटपुट सी कोड पोस्ट कर सकते हैं? –

0

जब साइथन धीमा हो जाता है, तो शायद यह रूपांतरण प्रकारों के कारण होता है, और संभावित रूप से प्रकार की टिप्पणियों की कमी से अधिक उत्तेजित होता है। इसके अलावा, यदि आप साइथन में सी डेटास्ट्रक्चर का उपयोग करते हैं, तो साइथन में पाइथन डेटास्ट्रक्चर का उपयोग करने से तेज़ हो जाएगा।

मैंने सीपीथॉन 2.x (सिथॉन के साथ और बिना साइको के साथ) के बिना प्रदर्शन तुलना की, सीपीथॉन 3.x (सिथॉन के साथ और बिना), पायपी और ज्योथन के बीच प्रदर्शन तुलना की।पापी अब तक सबसे तेज़ था, कम से कम माइक्रो-बेंचमार्क के लिए जांच: http://stromberg.dnsalias.org/~strombrg/backshift/documentation/performance/

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