2013-07-10 13 views
5

मैंने MATLAB में दो अलग-अलग तरीकों से कुछ कोड लिखा है। सबसे पहले, मैं छोरों के लिए दो का इस्तेमाल किया है, जो पहली नजर में बेवकूफ लगता है:क्यों (MATLAB में) यह कोड तेज़ है?

Initial = [zeros(10,1) ones(10,1)]; 

for xpop=1:10 
    for nvar=1:10 
     Parent(xpop,nvar) = Initial(nvar,1)+(Initial(nvar,2)-Initial(nvar,1))*rand(); 
    end 
end 

दूसरी योजना में, मैं vectorized गणना करने की कोशिश की (मैं यह तेजी से किया जा सकता है ग्रहण):

Parent = repmat(Initial(:,1),1,10) + rand(10,10).*(repmat(Initial(:,2),1,10)-repmat(Initial(:,1),1,10)); 

कोड के तीन विभिन्न समय में बीता हुआ समय निम्नलिखित देखा जा सकता है:

Elapsed time is 0.000456 seconds. 
Elapsed time is 0.006342 seconds. 

Elapsed time is 0.000457 seconds. 
Elapsed time is 0.006147 seconds. 

Elapsed time is 0.000471 seconds. 
Elapsed time is 0.006433 seconds. 

क्यों पहली योजना दूसरे की तुलना में तेजी है? क्या यह वास्तव में '। *' कमांड के अंदर loops के लिए दो बेवकूफ कर रहा है?

+4

मुझे उम्मीद है कि जब यह 'प्रारंभिक' बड़ा हो जाएगा तो यह बदल सकता है .. –

+2

यदि 10 के आयाम के बजाय, आप 1000 के आयाम का उपयोग करते हैं, तो आप विपरीत परिणाम देखेंगे। – tashuhka

+0

हाँ, सही लोग धन्यवाद – NKN

उत्तर

9

आपका परीक्षण सेटअप वेक्टरेशन के फायदे दिखाने के लिए बस बहुत छोटा है।

Initial = [zeros(10,1) ones(10,1)]; 
Elapsed time is 0.000078 seconds. 
Elapsed time is 0.000995 seconds. 
अब

एक बड़ा समस्या के लिए:

Initial = [zeros(1000,1) ones(1000,1)]; 
Elapsed time is 2.797949 seconds. 
Elapsed time is 0.049859 seconds. 
+1

संक्षेप में संक्षेप में, कुछ मामलों में (छोटे वैक्टर) लूप के लिए तेजी से होंगे, लेकिन अन्य मामलों (बड़े वैक्टर) वेक्टरेशन तेजी से होंगे। क्या कोई ज्ञात आकार है जहां दो अभिसरण इस प्रकार की सीमा को समझते हैं जो तेजी से है? – KronoS

+5

मैं कहूंगा कि यह _heavily_ प्रदर्शन किए गए सटीक ऑपरेशन पर निर्भर करता है। – Christoph

+2

@ क्रोनोएस एक लूप का उपयोग करके अभ्यास में वेक्टरकृत समकक्ष धड़कता है, शायद ही कभी आपके कुल कोड रनटाइम को एक सेकंड से नीचे लाएगा। दूसरी ओर एक अच्छा वेक्टरेशन अक्सर सेकंड या अधिक बचा सकता है। इस प्रकार जब तक कि आप किसी ऐसे व्यक्ति को अनुकूलित नहीं कर रहे हैं जिसे बड़ी मात्रा में कहा जाता है, तो प्रदर्शन प्राप्त करने के लिए परीक्षण लूप को परेशान न करें। –

3

यह आप इन बातों का परीक्षण करने के लिए अच्छा है। हालांकि आपको अच्छी जानकारी प्राप्त करने के लिए इन परीक्षणों को कैसे करना है, सीखना होगा।

सबसे पहले, लिया गया समय बहुत छोटा है, इसलिए दोहराव परीक्षण हमेशा सर्वोत्तम होते हैं। दूसरा, timeit जैसे टूल का उपयोग करें। यह आपके लिए सभी काम करता है, त्रुटि के कई स्रोतों को समाप्त करता है, हालांकि इसे एक फ़ंक्शन के रूप में अपना लक्ष्य encapsulated करने की आवश्यकता है।

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

आपको बीएसएक्सफ़ुन का उपयोग करना सीखना चाहिए, जो एक उपकरण है आपके द्वारा परीक्षण किए जा रहे फ़ॉर्म की कुछ गणनाओं को अनुकूलित करें। फिर, छोटी समस्याएं अक्सर गति में ज्यादा लाभ नहीं दिखाएंगी, यदि कोई हो।

अगला, जेआईटी के साथ समस्याएं हैं, कुछ सरल कोड अनुकूलित करने के लिए MATLAB में त्वरण। यदि वह (आपके लिए अदृश्य) उपकरण आपके द्वारा परीक्षण किए जा रहे कोड को अच्छी तरह से संभालने का प्रबंधन करता है, तो ऐसा लगता है जैसे लूप तेज है।

कुछ परीक्षण करना अच्छा है, इसलिए तुलना करें। चूंकि आपके उदाहरण सभी मुख्य रूप से इनलाइन हैं, इसलिए मैं बस प्रत्येक मामले के चारों ओर एक बड़ा पाश डाल दूंगा। यह परीक्षण त्रुटि के बड़े स्रोतों में से एक को कम करेगा।

Ktot = 100; 
N = 10; 
Initial = [zeros(N,1) ones(N,1)]; 

tic 
for k = 1:Ktot 
    for xpop=1:N 
    for nvar=1:N 
     Parent(xpop,nvar) = Initial(nvar,1)+(Initial(nvar,2)-Initial(nvar,1))*rand(); 
    end 
    end 
end 
toc 

tic 
for k = 1:Ktot 
    Parent = repmat(Initial(:,1),1,N) + rand(N,N).*(repmat(Initial(:,2),1,N)-repmat(Initial(:,1),1,N)); 
end 
toc 

क्या आप अपना सदिशित रूप सुधार सकते हैं? दो repmats क्यों, जब कोई भी काम करेगा?

tic 
for k = 1:Ktot 
    Parent = repmat(Initial(:,1),1,N) + rand(N,N).*repmat(Initial(:,2)-Initial(:,1),1,N); 
end 
toc 

bsxfun के बारे में क्या?

tic 
for k = 1:Ktot 
    Parent = bsxfun(@plus,Initial(:,1),bsxfun(@times,rand(N,N),Initial(:,2)-Initial(:,1))); 
end 
toc 

तो, एन = 10 और Ktot = 100 के साथ, मैं कई बार इस तरह देखें:

Elapsed time is 0.003935 seconds. 
Elapsed time is 0.012250 seconds. 
Elapsed time is 0.008269 seconds. 
Elapsed time is 0.004304 seconds. 

फिर, यह एक छोटी सी समस्या है। अगर हम समस्या का विस्तार करते हैं तो क्या होता है? N = 10.

Elapsed time is 0.131186 seconds. 
Elapsed time is 0.031671 seconds. 
Elapsed time is 0.027205 seconds. 
Elapsed time is 0.019763 seconds. 

तो हमने वहां कुछ और तर्कसंगत तरीके से सॉर्टिंग की चीजें देखीं। अब bsxfun संस्करण कुछ लाभ दिखाने शुरू कर रहा है। इसके बाद, जबकि कुछ अधिक भूमि के ऊपर है एन तक जा = 1000.

Elapsed time is 12.288608 seconds. 
Elapsed time is 3.412531 seconds. 
Elapsed time is 2.690691 seconds. 
Elapsed time is 1.626599 seconds. 

अनिवार्य रूप से, इन कोड के सभी एक ही काम करते हैं, यह है कि वे किस तरह कुछ समस्या संरचना में अधिक कुशल हैं सिर्फ इतना है कि,। जैसा कि हम बड़ी समस्याओं में देखते हैं, स्पष्ट लूप फ्लैट गिरते हैं।

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