2012-02-25 4 views
12

के साथ अजगर की तुलना में मैंने सी/किलरान के साथ अजगर की गति की तुलना करने के लिए निम्नलिखित कार्यक्रम लिखे हैं। प्रोग्राम द्वारा उपयोग किए जाने वाले समय को पाने के लिए मैंने "टाइम" कमांड का उपयोग किया। सभी प्रोग्राम x x + y y + z * z के वर्ग रूट की गणना करते हैं जहां x, y, z फ़्लोट होते हैं। मैंने रूट स्क्वायर का उपयोग किया क्योंकि यह वैज्ञानिक कंप्यूटिंग में सबसे अधिक समय लेने वाले हिस्सों में से एक है, जिसमें मैं शामिल हूं। साधारण परीक्षण मैं मैंने पाया कि अजगर वैज्ञानिक कंप्यूटिंग के लिए अनुशंसित नहीं है किया था के अनुसारसी/फोर्ट्रान

fortran 0m29.9s // 
c  0m20.7s // 
python 30m10.8s 

:

मैं निम्नलिखित समय मिला है। लेकिन शायद मेरा कोड बहुत अक्षम है।

क्या आपको लगता है कि मैं इस सरल परीक्षण मामले के लिए अपना कोड अधिक कुशल बना सकता हूं?

फोरट्रान:

program root_square 
implicit none 

integer i,j 
real x,y,z,r 

x=1.0 
y=2.0 
z=3.0 

do j=1,3000 
    do i=1,1000000 
     r=sqrt(x*x+y*y+z*z) 
    enddo 
enddo 

end program root_square 

सी:

#include "stdio.h" 
#include "math.h" 

int main (void) 
{ 

float x=1.0,y=2.0,z=3.0,r; 
int i,j; 

for(j=0; j<3000; j++){ 
     for(i=0; i<1000000; i++) { 
       r=sqrt(x*x+y*y+z*z); 
     } 
} 

return 0; 
} 

पायथन:

#!/usr/bin/env python 

from math import sqrt 

x = 1.0 
y = 2.0 
z = 3.0 

for j in range(1,3001): 
    for i in range(1,1000001): 
    r = sqrt(x*x+y*y+z*z) 
+0

सबसे पहले, सी उदाहरण में 'z', 'y' और' z' अनियमित हैं। – Hauleth

+4

आपका पायथन कोड संख्याओं की दो सूचियां बनाता है, एक 3000 नंबर के साथ और 100,000 नंबरों वाला एक। जब आप सी या फोरट्रान में नहीं करते हैं तो आप पायथन में ऐसा क्यों करते हैं? इसके अलावा, पायथन में आप सी और फोरट्रान में डबल परिशुद्धता फ़्लोटिंग पॉइंट का उपयोग करते हैं, आप केवल एक परिशुद्धता का उपयोग करते हैं। क्यूं कर? –

+0

असल में, एक सार्थक तुलना के लिए, आप यह भी करना चाहेंगे: (i) ऑप्टिमाइज़ेशन सक्षम (जैसे) जीसीसी के लिए '-O3 -march = native' की तरह smth, 'इंटेल के लिए'fast'), और यह भी (ii) संशोधित करें लूप ताकि गणना को लूप के बाहर स्थानांतरित नहीं किया जा सके (उदाहरण के लिए 'आर = आर + एसकर्ट ((i + j) * x * x + y * y + z * z) ', और' प्रिंट * जैसे smth, अंत में आर') - क्योंकि संकलक अनुकूलन आपके लिए ऐसा करेंगे। जैसा कि किसी ने कहा था, अगर आपको डबल परिशुद्धता (जो अजगर के मामले में है) की आवश्यकता है, तो आपको क्रमशः फोरट्रान और सी में 'असली * 8' और' डबल' का उपयोग करना चाहिए। – laxxy

उत्तर

14

मैं हाल ही में एक और अधिक यथार्थवादी वास्तविक दुनिया एल्गोरिथ्म के साथ a similar test किया है। इसमें numpy, Matlab, FORTRAN और C# (ILNumerics के माध्यम से) शामिल है। विशिष्ट अनुकूलन के बिना, numpy दूसरों की तुलना में बहुत कम कुशल कोड उत्पन्न करने के लिए प्रतीत होता है। बेशक - हमेशा के रूप में - यह केवल एक सामान्य प्रवृत्ति का सुझाव दे सकता है। आप फोरट्रान कोड लिखने में सक्षम होंगे जो अंत में एक समान numpy कार्यान्वयन से धीमी गति से चलता है। लेकिन ज्यादातर समय, numpy बहुत धीमी हो जाएगी। यहाँ (औसत) अपने परीक्षण के परिणाम: अपने उदाहरण के रूप में समय में इस तरह के सरल चल बिन्दु आपरेशनों के लिए

kmeans comparison results

क्रम में, सभी compilers 'इष्टतम' मशीन निर्देश उत्पन्न करने की क्षमता के लिए नीचे आता है। यहां, यह इतना महत्वपूर्ण नहीं है कि कितने संकलन चरण शामिल हैं। .NET और numpy पहले एक बाइट कोड को संकलित करके एक से अधिक चरणों का उपयोग करते हैं जो वर्चुअल मशीन में निष्पादित करने से अधिक है। लेकिन परिणाम को अनुकूलित करने के विकल्प समान रूप से मौजूद हैं - सिद्धांत में। प्रैक्सिस में, आधुनिक फोरट्रान और सी कंपाइलर निष्पादन गति के अनुकूलन में बेहतर हैं। एक उदाहरण के रूप में वे फ़्लोटिंग पॉइंट एक्सटेंशन (एसएसई, एवीएक्स) का उपयोग करते हैं और बेहतर लूप अनोलिंग करते हैं। numpy (या बेहतर CPython, जो ज्यादातर numpy द्वारा उपयोग किया जाता है) इस बिंदु पर और भी खराब प्रदर्शन प्रतीत होता है। यदि आप यह सुनिश्चित करना चाहते हैं कि आपके कार्य के लिए कौन सा ढांचा सर्वोत्तम है, तो आप डीबगर से संलग्न हो सकते हैं और निष्पादन योग्य के अंतिम मशीन निर्देशों की जांच कर सकते हैं।

हालांकि, ध्यान रखें, एक और यथार्थवादी परिदृश्य में फ्लोटिंग पॉइंट प्रदर्शन केवल एक बड़ी अनुकूलन श्रृंखला के अंत में महत्वपूर्ण है। अंतर अक्सर एक बहुत मजबूत प्रभाव से मुखौटा होता है: मेमोरी बैंडविड्थ। जैसे ही आप सरणी को संभालना शुरू करते हैं (जो अधिकांश वैज्ञानिक अनुप्रयोगों में आम है) आपको स्मृति प्रबंधन की लागत को ध्यान में रखना होगा। फ्रेमवर्क स्मृति कुशल एल्गोरिदम लिखने में एल्गोरिदम लेखक का समर्थन करने में विचलित हो जाते हैं। मेरी राय में numpy मेमोरी कुशल एल्गोरिदम लिखने के लिए कठिन बनाता है तो फोरट्रान या सी। लेकिन किसी भी थोज भाषा में यह आसान नहीं है। (ILNumerics इस काफी सुधार करता है।)

एक और महत्वपूर्ण बिंदु समांतरता है। क्या ढांचा आपके समरूपता को समानांतर में निष्पादित करने में सहायता करता है? और यह कितना कुशल है? फिर मेरी व्यक्तिगत राय: न तो सी और न ही फोरट्रान और न ही numpy आपके एल्गोरिदम समानांतर करना आसान बनाता है। लेकिन फोरट्रान और सी कम से कम आपको ऐसा करने का मौका देते हैं, भले ही इसे कभी-कभी विशेष कंपाइलर्स का उपयोग करने की आवश्यकता होती है।अन्य ढांचे (ILNumerics, Matlab) स्वचालित रूप से समानांतर करते हैं।

यदि आपको बहुत छोटे लेकिन महंगी एल्गोरिदम के लिए 'चरम प्रदर्शन' की आवश्यकता है तो आप अधिकतर फोरट्रान या सी का उपयोग करना बंद कर देंगे। क्योंकि अंत में वे बेहतर मशीन कोड (एक यूनिप्रोसेसर सिस्टम पर) उत्पन्न करते हैं। हालांकि, सी या फोरट्रान और में बड़ी एल्गोरिदम लिखना स्मृति दक्षता और खाते में समांतरता अक्सर बोझिल हो जाता है। यहां, निम्न स्तर की भाषाएं (जैसे numpy, ILNumerics या Matlab) निम्न स्तर की भाषाएं हैं। और यदि सही हो - निष्पादन गति में अंतर अकसर नगण्य है। दुर्भाग्य से, यह अक्सर numpy के मामले के लिए सच नहीं है।

+0

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

+0

@steabert दाएं। मैं स्पष्ट करने की कोशिश कर रहा था, sqrt() फ़ंक्शन अलग नहीं रह सकता है। एक असली दुनिया परिदृश्य में, एक भाषा का फैसला करने के लिए खाते में ध्यान देने के लिए और अधिक विचार होना चाहिए। –

3

आप वास्तव में नहीं समझाया है अपने माप का लक्ष्य क्या है, तो यह बहुत मुश्किल है जवाब दें कि आपका टेस्ट कोड पर्याप्त रूप से उस लक्ष्य को पूरा करने के लिए जानकारी प्रदान करेगा या नहीं। आम तौर पर, बेंचमार्क आपको कुछ विशिष्ट बताते हैं - आपको पता होना चाहिए कि आप बेंचमार्क आयोजित करके क्या पता लगाने की कोशिश कर रहे हैं। जिस प्रकार आप उपरोक्त कोशिश कर रहे हैं, उसके माइक्रोबेंमार्क, विकृत उत्तरों प्रदान करने के लिए भी कुख्यात हैं ...

4

नियम के रूप में, पायथन में वैज्ञानिक गणनाओं के लिए numpy का उपयोग किया जाता है। आपको शायद उस lib का परीक्षण करना चाहिए।

3

शायद आप कर सकते हैं। पाइथन के लिए कई गणित पुस्तकालय हैं जो शायद वह कार्य कर सकते हैं जो आप थोड़ा अधिक कुशल चाहते हैं। चूंकि अजगर श्रृंखला सी लूप से काफी अलग काम करती है, इसलिए मैं इन लूपों को पहले अनलॉक करने का प्रयास करूंगा।

4

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

2

इस तरह के समय की तुलना करना शुरू करने से पहले आपको कई चीजें अवगत रहनी चाहिए।

  1. जैसा कि एक अन्य उत्तर में बताया गया है, यह हो सकता है कि संकलक लूप और वास्तविक मूल्य को दूर करता है। इसके अलावा, भले ही आप परिणाम प्रिंट करते हैं, यह केवल वर्ग रूट को पूर्व-गणना कर सकता है।
  2. आप फोरट्रान में real और सी में float उपयोग कर रहे हैं, तो (बेशक आपके सिस्टम पर निर्भर करता है) संकलक शायद, फोरट्रान में sqrtf पुस्तकालय कॉल का उपयोग करेगा, जबकि सी में आप sqrtf के बजाय sqrt है, जो आप के लिए उपयोग करना चाहिए का उपयोग एक float
  3. पायथन में, आपको numpy और scipy पैकेजों का उपयोग करना चाहिए, वे तीर प्रदान करते हैं जिन पर आप पाइथन में लूपिंग से परहेज करते हुए कुशल पूर्ण-सरणी संचालन कर सकते हैं।
5

त्रुटिपूर्ण बेंचमार्क।

यदि आप समय फ्लोटिंग पॉइंट अंकगणित करना चाहते हैं, तो आपको पहली बार लूप कुछ भी नहीं करना चाहिए (या जैसा कि आप प्रबंधित कर सकते हैं के करीब कुछ भी नहीं)। पूरे लूप को अनुकूलित करने से बचने के लिए, सुनिश्चित करें कि यह एक बाइट चार को एक सरणी से दूसरे में ले जाने जैसा कुछ कर रहा है।

फिर इसे फिर से फ़्लोटिंग पॉइंट गणना के साथ और अधिक सटीक संख्या प्राप्त करने के लिए पहली बार घटाएं।

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

+0

+1। लेकिन मुझे लगता है, ओपी न केवल एफपी प्रदर्शन के बारे में चिंतित है, बल्कि सामान्य रूप से भाषा व्यवहार्यता के बारे में चिंतित है। इसलिए, इसी तरह के कंपाइलर का अनुवाद और लूप को अनुकूलित करने का तरीका भी महत्वपूर्ण है। –

+0

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

+0

मैं सहमत हूं। फिर भी, वे हमेशा परिस्थितियों को कम करना चाहते हैं, जहां भाषा सीमा पार करना निरंतर है। मैंने इसे 'क्यों लिखा है .... एल्गोरिदम इतनी धीमी है?' प्रशन। –

0

गणना मैं Haskell या मिलीलीटर की कोशिश कर सकते के लिए ...

एमएल में इस कोड का प्रयास करें:

fun trip(x,y,z) = if y=z then 0 
    else trip(((Math.sqrt((1.0*1.0)+(2.0*2.0)+(3.0*3.0)))*1.0),(y+1),z); 
trip(1.0,1,300000000); 
+0

भाषा को स्विच करना बहुत क्रूड अनुकूलन प्रतीत होता है। – PVitt