Questa è una domanda successiva a an answer I gave a few days back. Modifica: sembra che l'OP di quella domanda abbia già utilizzato il codice che gli ho inviato per chiedere the same question, ma non ne ero a conoscenza. Scuse. Le risposte fornite sono diverse però!Perché il ritorno anticipato è più lento di altri?
Sostanzialmente ho osservato che:
>>> 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]
... o in altre parole: avere la clausola else
è più veloce indipendentemente dalla condizione if
essere attivato o meno.
Suppongo che abbia a che fare con diversi bytecode generati dai due, ma qualcuno è in grado di confermare/spiegare in dettaglio?
EDIT: Sembra che non tutti siano in grado di riprodurre i tempi, quindi ho pensato che potrebbe essere utile fornire alcune informazioni sul mio sistema. Sto usando Ubuntu 11.10 64 bit con il python predefinito installato. python
genera le seguenti informazioni di versione:
Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
[GCC 4.6.1] on linux2
Ecco i risultati del disassemblaggio 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
c'era una domanda identica su SO non riesco a trovare ora. Hanno controllato il codice byte generato e c'era un ulteriore passaggio. Le differenze osservate erano molto dipendenti dal tester (macchina, SO ..), a volte trovando solo differenze molto piccole. – joaquin
Su 3.x, entrambi producono ** bytecode ** identico salvo per un codice non raggiungibile ('LOAD_CONST (None); RETURN_VALUE' - ma come detto, non viene mai raggiunto) alla fine di' with_else'. Dubito fortemente che il codice morto renda una funzione più veloce. Qualcuno potrebbe fornire un 'dis' su 2.7? – delnan
Non ero in grado di riprodurre questo. La funzione con 'else' e' False' era la più lenta di tutte (152ns). Il secondo più veloce è stato 'True' senza' else' (143ns) e altri due erano sostanzialmente gli stessi (137ns e 138ns). Non ho usato il parametro di default e l'ho misurato con '% timeit' in iPython. – rplnt