2013-07-23 11 views
26

इस पर एक नज़र डालें:ये दो कार्य अलग क्यों हैं?

>>> def f(): 
...  return (2+3)*4 
... 
>>> dis(f) 
    2   0 LOAD_CONST    5 (20) 
       3 RETURN_VALUE 

जाहिर है, संकलक पूर्व का मूल्यांकन किया गया है (2+3)*4, जो समझ में आता है।

अब, अगर मैं बस * की ऑपरेंड का क्रम बदल:

>>> def f(): 
...  return 4*(2+3) 
... 
>>> dis(f) 
    2   0 LOAD_CONST    1 (4) 
       3 LOAD_CONST    4 (5) 
       6 BINARY_MULTIPLY  
       7 RETURN_VALUE 

अभिव्यक्ति नहीं रह गया है पूरी तरह से पूर्व मूल्यांकन किया जाता है! इसका कारण क्या है? मैं सीपीथन 2.7.3 का उपयोग कर रहा हूँ।

+2

मुझे पेफोल अनुकूलक में एक दोष की तरह दिखता है। आप बग ट्रैकर की जांच कर सकते हैं और देख सकते हैं कि यह एक ज्ञात समस्या है या नहीं। – user2357112

+4

पुरानी पायथन 2.x का उपयोग करना बंद करें ... 3.3 (कम से कम) पर यह काम करता है जैसा कि इसे करना चाहिए। – JBernardo

+1

@ जेबेर्नर्डो 2.x और 3.x बहुत अलग हैं; मैं उनके बीच सहजता से स्विच नहीं कर सकता। – arshajii

उत्तर

9

पहले मामले में unoptimized कोड LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY है और दूसरे मामले में यह LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY है। fold_binops_on_constants() में पैटर्न मैचर को पहले ADD ठीक से संभालना होगा (LOAD LOAD ADD को LOAD के साथ प्रतिस्थापित करना) और फिर MULTIPLY पर एक ही चीज़ करने के लिए निम्नानुसार है। दूसरे मामले में ADD (अब पहले के बजाय MULTIPLY पर दूसरा तर्क) स्थिर हो गया है स्कैनर L L M देखने के लिए बहुत दूर है (जब "कर्सर" LOAD 4 पर ऐसा नहीं था एक L L M अभी तक)।

+0

तो यह संकलक की कमी है, तो? – arshajii

+3

@arshajii: आप शायद एक गुना के बाद एक निर्देश का बैक अप करके 'peephole.c' में बग को ठीक कर सकते हैं। हालांकि सही समाधान पेफोल ऑप्टिमाइज़र पर निर्भर नहीं है और इसके बजाय 'compile.c' में फोल्ड स्थिरांक है जहां यह पहली जगह बिनोप्स उत्सर्जित कर रहा है। एएसटी पर एक पास पत्तियों से निरंतर अभिव्यक्ति की जानकारी प्रसारित कर सकता है और इस तरह की बग के लिए कोई जगह नहीं होगी। –

5

ऐसा लगता है कि इस समस्या को पायथन 3.3 में पैच किया गया था, जैसा कि here देखा जा सकता है।

>>> def f(): 
...  return (2+3)*4 
... 
>>> dis(f) 
    2   0 LOAD_CONST    5 (20) 
       3 RETURN_VALUE 
>>> def f(): 
...  return 4*(2+3) 
... 
>>> dis(f) 
    2   0 LOAD_CONST    5 (20) 
       3 RETURN_VALUE 
संबंधित मुद्दे