[python] Warum ist die frühe Rückkehr langsamer als sonst?


Answers

Question

Dies ist eine Folgefrage zu einer Antwort, die ich vor ein paar Tagen gegeben habe . Edit: Es scheint, dass der OP dieser Frage den Code, den ich ihm geschrieben habe, bereits benutzt hat, um die gleiche Frage zu stellen , aber ich war mir dessen nicht bewusst. Entschuldigung. Die Antworten sind jedoch unterschiedlich!

Im Wesentlichen habe ich beobachtet, dass:

>>> def without_else(param=False):
...     if param:
...         return 1
...     return 0
>>> def with_else(param=False):
...     if param:
...         return 1
...     else:
...         return 0
>>> from timeit import Timer as T
>>> T(lambda : without_else()).repeat()
[0.3011460304260254, 0.2866089344024658, 0.2871549129486084]
>>> T(lambda : with_else()).repeat()
[0.27536892890930176, 0.2693932056427002, 0.27011704444885254]
>>> T(lambda : without_else(True)).repeat()
[0.3383951187133789, 0.32756996154785156, 0.3279120922088623]
>>> T(lambda : with_else(True)).repeat()
[0.3305950164794922, 0.32186388969421387, 0.3209099769592285]

... oder mit anderen Worten: Die else Klausel ist schneller, unabhängig davon, if die if Bedingung ausgelöst wird oder nicht.

Ich nehme an, es hat mit unterschiedlichen Bytecodes zu tun, die von den beiden erzeugt werden, aber kann jemand im Detail bestätigen / erklären?

EDIT: Scheint nicht jeder ist in der Lage, meine Timings zu reproduzieren, also dachte ich, dass es nützlich sein könnte, einige Informationen über mein System zu geben. Ich benutze Ubuntu 11.10 64 Bit mit dem Standard-Python installiert. python generiert die folgenden Versionsinformationen:

Python 2.7.2+ (default, Oct  4 2011, 20:06:09) 
[GCC 4.6.1] on linux2

Hier sind die Ergebnisse der Disassemblierung in Python 2.7:

>>> dis.dis(without_else)
  2           0 LOAD_FAST                0 (param)
              3 POP_JUMP_IF_FALSE       10

  3           6 LOAD_CONST               1 (1)
              9 RETURN_VALUE        

  4     >>   10 LOAD_CONST               2 (0)
             13 RETURN_VALUE        
>>> dis.dis(with_else)
  2           0 LOAD_FAST                0 (param)
              3 POP_JUMP_IF_FALSE       10

  3           6 LOAD_CONST               1 (1)
              9 RETURN_VALUE        

  5     >>   10 LOAD_CONST               2 (0)
             13 RETURN_VALUE        
             14 LOAD_CONST               0 (None)
             17 RETURN_VALUE        



Links