2011-06-13 11 views
8

संभव डुप्लिकेट:
Performance difference between functions and pattern matching in Mathematicaगणित कोड में शुद्ध कार्य तेजी से क्यों हैं?

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

+1

संबंधित http://stackoverflow.com/questions/4187822/performance-difference-between-functions-and-pattern-matching-in-mathematica/4190348#4190348 –

+0

अरे! यह फिर से हो रहा है। एमएमए टैग "गणित" –

+1

के साथ भ्रमित हो जाता है, जहां आपको उसकी आवश्यकता होने पर @Leonid है ... – acl

उत्तर

8

पहले, हमें कुछ नमूना मानक पर विचार करते हैं:

In[100]:= f[x_]:=x^2; 

In[102]:= Do[#^2&[i],{i,300000}]//Timing 
Out[102]= {0.406,Null} 

In[103]:= Do[f[i],{i,300000}]//Timing 
Out[103]= {0.484,Null} 

In[104]:= Do[Function[x,x^2][i],{i,300000}]//Timing 
Out[104]= {0.578,Null} 

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

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

In[117]:= ff[x_] := Sqrt[x]; 

In[116]:= Map[Sqrt[#] &, [email protected][100000]]; // Timing 

Out[116]= {0.015, Null} 

In[114]:= Map[ff, [email protected][100000]]; // Timing 

Out[114]= {0.094, Null} 
+1

उन सीमाओं (ऑटोकंपिलेशन के लिए) सिस्टमऑप्शन ["संकलन विकल्प"] द्वारा पाई जा सकती हैं।वे सेट सिस्टम सिस्टम ["संकलन विकल्प" -> "संकलन रिपोर्ट" -> सत्य] द्वारा सेट किया जा सकता है। यह विशेष उदाहरण दिलचस्प है, लेकिन अगर आप हिस्टोग्राम का बहुत उपयोग करते हैं तो परेशान :) – acl

+0

अच्छा जवाब लेकिन मुझे समझ में नहीं आता कि आप क्यों कहते हैं "पैटर्न-परिभाषित मूल मौलिक रूप से नहीं कर सकते"? –

+0

ओह, और यह इंगित करने लायक हो सकता है कि "शुद्ध कार्य" का एक प्रसिद्ध अर्थ है और यह नहीं है। :-) –

-1

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

+0

आपका उत्तर टैग के साथ संबंधित (या केवल अस्पष्ट) प्रतीत नहीं होता है। कृपया http://www.wolfram.com/mathematica/ –

+1

देखें जो @belisarius ने कहा था, गणित की बात आने पर इसका हिस्सा भी सच नहीं है। उदाहरण के लिए इसे चलाएं और शुद्ध कार्य का पालन करें, वास्तविक समय में और अपनी आंखों से पहले, अपने तर्क को बदलें :): lst = {}; गतिशील [lst] क्या करें [फ़ंक्शन [{u, i}, Appendto [u, i], HoldAll] [lst, i]; रोकें [1] ;, {i, 3}] और [lst] – acl

+0

ठीक है, मैं सबसे बड़ा गणित आंतरिक गुरु नहीं हूं, लेकिन मैं इसे अक्सर उपयोग करता हूं। मुझे लगता है कि ओपी शुद्ध प्रसंस्करण एल्गोरिदम की अधिक सोच रहा था, 'शुद्ध तालिका के लिए कितनी तेजी से कॉल कर रहे हैं, बस' एक टेबल बनाएं, प्रक्रिया करें, कम करें, निकालें 'टाइप करें। –

0

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

तो, यदि संकलक ऑप्टिमाइज़ेशन को इन फ़ंक्शन के सापेक्ष प्रबंधित करने में सक्षम है, तो आपका प्रोग्राम तेज़ होगा। जो भी लंगेज है।

+1

पर है, तो गणित में एक कंपाइलर नहीं है, या कम से कम आपके मन में नहीं है :) (यह एमएमए में शुद्ध कार्यों के बारे में एक सवाल है , सामान्य रूप से नहीं, जब तक कि मैं गलत नहीं हूं) – acl

+0

एमएमए दुभाषिया उन चीजों में से कई कर सकता है, जैसे कॉपी द्वारा तर्क न दें, लेकिन मुझे सामान्य मामले में जवाब देने में कोई कमी नहीं दिखती है। – deadalnix

+1

@acl Mathematica मैप किए गए सूची के आकार के आधार पर, 'मानचित्र' में फ़ंक्शन संकलित करेगा। (यह कई अन्य कार्यों के लिए भी वही करेगा, विभिन्न सीमाओं के लिए एक महसूस करने के लिए 'सिस्टमऑप्शन ["संकलन विकल्प"] देखें।) –

0

असल में, पैटर्न मिलान आमतौर पर Function[{u},...] निर्माण से तेज़ लगता है और #&-प्रकार के निर्माण (संकलन की संभावना को अनदेखा कर रहा है, जो एमएमए 8 में अधिक रोमांचक हो गया है)।

SetAttributes[timeshort, HoldAll]; 
timeshort[expr_] := Module[{t = Timing[expr;][[1]], tries = 1}, 
    While[t < 1., 
     tries *= 2; 
     t = Timing[Do[expr, {tries}];][[1]]]; 
    Return[t/tries]] 

तो इस कोशिश:

इस समय के लिए कोड की कमी टुकड़े एक समारोह को परिभाषित देखने के लिए

ClearAll[f]; f[x_] := Cos[x] 
Trace[f[5.]] 
f[5] // timeshort 

ClearAll[f]; f = Function[x, Cos[x]] 
Trace[f[5.]] 
f[5] // timeshort 

ClearAll[f]; f = Cos[#] & 
Trace[f[5.]] 
f[5] // timeshort 

जो दे

{f[5.],Cos[5.],0.283662} 
8.45641\[Times]10^-7 
Function[x,Cos[x]] 
{{f,Function[x,Cos[x]]},Function[x,Cos[x]][5.],Cos[5.],0.283662} 
1.51906\[Times]10^-6 
Cos[#1]& 
{{f,Cos[#1]&},(Cos[#1]&)[5.],Cos[5.],0.283662} 
8.04602\[Times]10^-7 

है कि, पैटर्न मिलान और #&Function से तेज़ हैं। मुझे कोई जानकारी नहीं है की क्यों।

संपादित करें: मान लीजिए कि मुझे पहले सुझाए गए प्रश्न बेलीसियस की जांच करनी चाहिए ... here अनिवार्य रूप से वही उत्तर देने के लिए देखें, और कुछ रोचक चर्चाओं के लिए टिप्पणियां भी पढ़ें।

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