¿Por qué estas dos funciones son diferentes?
Echa un vistazo a esto:
>>> def f():
... return (2+3)*4
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE
Evidentemente, el compilador ha pre-evaluado (2+3)*4
, lo cual tiene sentido.
Ahora, si simplemente cambio el orden de los operandos de *
:
>>> 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
¡La expresión ya no está completamente pre-evaluada! ¿Cuál es la razón de esto? Estoy usando CPython 2.7.3.
2 answers
En el primer caso el código no optimizado es LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY
y en el segundo caso es LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY
. El pattern matcher en fold_binops_on_constants()
debe manejar el primer ADD
ok (reemplazando LOAD LOAD ADD
con LOAD
) y luego seguir haciendo lo mismo con MULTIPLY
. En el segundo caso cuando el ADD
(ahora el segundo argumento de MULTIPLY
en lugar del primero) se convierte en una constante, el escáner está demasiado adelantado para ver L L M
(cuando el "cursor" estaba encendido LOAD 4
todavía no parecía un L L M
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-23 01:32:04
Parece que este problema fue parcheado en Python 3.3, como se puede ver aquí.
>>> 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 19:17:53