2013-08-08 8 views
18

if True पाइथन में if 1 से धीमा क्यों है? if Trueif 1 से तेज़ नहीं होना चाहिए?यदि सच है तो 1 से कम धीमा क्यों है?

मैं timeit मॉड्यूल सीखने की कोशिश कर रहा था। मूल बातें के साथ शुरू, मैंने कोशिश की इन:

>>> def test1(): 
...  if True: 
...   return 1 
...  else: 
...   return 0 

>>> print timeit("test1()", setup = "from __main__ import test1") 
0.193144083023 


>>> def test2(): 
...  if 1: 
...   return 1 
...  else: 
...   return 0 

>>> print timeit("test2()", setup = "from __main__ import test2") 
0.162086009979 


>>> def test3(): 
...  if True: 
...    return True 
...  else: 
...    return False 

>>> print timeit("test3()", setup = "from __main__ import test3") 
0.214574098587 

>>> def test4(): 
...  if 1: 
...    return True 
...  else: 
...    return False 

>>> print timeit("test4()", setup = "from __main__ import test4") 
0.160849094391 

मैं इन बातों से उलझन में हूँ:

  1. this question में श्री सिल्वेन Defresne से प्रतिक्रिया के अनुसार, सब कुछ परोक्ष एक bool पहले में बदल जाती है और फिर चेक किया। तो if Trueif 1 से धीमा क्यों है?
  2. test3test1 से धीमा क्यों है, भले ही return मान अलग हैं?
  3. प्रश्न 2 की तरह, लेकिन test4test2 से थोड़ा क्यों है?

नोट: मैं timeit तीन बार भाग गया और परिणामों का औसत लिया, फिर कोड के साथ यहां समय पोस्ट किया।

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

+0

मुझे लगता है कि आपके परीक्षण बहुत छोटे हैं। और तीन रनों का औसत पर्याप्त नहीं है: पी – keyser

+0

मैं समझता हूं :) यहां तक ​​कि टेस्ट केस भी सोचने के लिए बहुत बुनियादी है।हालांकि, हमें कहीं भी सही शुरू करने की आवश्यकता है :) – thiruvenkadam

+0

संभावित डुप्लिकेट [माइक्रोबेंमार्क को कब तक चलने की आवश्यकता है?] (Http://stackoverflow.com/questions/2857470/how-long-does-a-microbenchmark-need- टू रन) –

उत्तर

23

True और FalsePython 2 में कीवर्ड नहीं हैं।

उन्हें रनटाइम पर हल करना होगा। यह अजगर 3 पर Python 3

एक ही टेस्ट मैच में बदल दिया गया है:

>>> timeit.timeit('test1()',setup="from __main__ import test1", number=10000000) 
2.806439919999889 
>>> timeit.timeit('test2()',setup="from __main__ import test2", number=10000000) 
2.801301520000038 
>>> timeit.timeit('test3()',setup="from __main__ import test3", number=10000000) 
2.7952816800000164 
>>> timeit.timeit('test4()',setup="from __main__ import test4", number=10000000) 
2.7862537199999906 

समय त्रुटि 1% है, जो स्वीकार्य है में है।

+2

से टाइप करने के लिए 4 गुना अधिक समय लगता है 'सत्य, गलत = गलत, सही' – Kabie

17

बाइटकोड डिस्सेप्लर अंतर स्पष्ट बनाता है।

>>> dis.dis(test1) 
    2   0 LOAD_GLOBAL    0 (True) 
       3 JUMP_IF_FALSE   5 (to 11) 
       6 POP_TOP    

    3   7 LOAD_CONST    1 (1) 
      10 RETURN_VALUE   
     >> 11 POP_TOP    

    5   12 LOAD_CONST    2 (0) 
      15 RETURN_VALUE   
      16 LOAD_CONST    0 (None) 
      19 RETURN_VALUE   

Kabie उल्लेख किया है, True और False वैश्विक अजगर में 2. सामान के बहुत सारे उन तक पहुँचने के लिए पर जा रहा है कर रहे हैं।

>>> dis.dis(test2) 
    3   0 LOAD_CONST    1 (1) 
       3 RETURN_VALUE   

अजगर संकलक 1 एक लगातार "truthy" अभिव्यक्ति के रूप में समझते हैं और अनावश्यक हालत दूर अनुकूलित कर सका!

>>> dis.dis(test3) 
    2   0 LOAD_GLOBAL    0 (True) 
       3 JUMP_IF_FALSE   5 (to 11) 
       6 POP_TOP    

    3   7 LOAD_GLOBAL    0 (True) 
      10 RETURN_VALUE   
     >> 11 POP_TOP    

    5   12 LOAD_GLOBAL    1 (False) 
      15 RETURN_VALUE   
      16 LOAD_CONST    0 (None) 
      19 RETURN_VALUE   

सुंदर ज्यादा test1 रूप में एक ही, एक और LOAD_GLOBAL साथ।

>>> dis.dis(test4) 
    3   0 LOAD_GLOBAL    0 (True) 
       3 RETURN_VALUE   

test2 देखें। लेकिन LOAD_GLOBALLOAD_CONST से थोड़ा अधिक महंगा है।

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