Commit dd80f762 authored by Raymond Hettinger's avatar Raymond Hettinger

SF patch #910929: Optimize list comprehensions

Add a new opcode, LIST_APPEND, and apply it to the code generation for
list comprehensions.  Reduces the per-loop overhead by about a third.
parent bff63f03
...@@ -288,6 +288,10 @@ yellow 5 ...@@ -288,6 +288,10 @@ yellow 5
use as arguments to functionals: use as arguments to functionals:
\samp{map(mydict.__getitem__, keylist)}. \samp{map(mydict.__getitem__, keylist)}.
\item Added an newcode opcode, \code{LIST_APPEND}, that simplifies
the generated bytecode for list comprehensions and speeds them up
by about a third.
\end{itemize} \end{itemize}
The net result of the 2.4 optimizations is that Python 2.4 runs the The net result of the 2.4 optimizations is that Python 2.4 runs the
......
...@@ -21,6 +21,7 @@ extern "C" { ...@@ -21,6 +21,7 @@ extern "C" {
#define UNARY_INVERT 15 #define UNARY_INVERT 15
#define LIST_APPEND 18
#define BINARY_POWER 19 #define BINARY_POWER 19
#define BINARY_MULTIPLY 20 #define BINARY_MULTIPLY 20
......
...@@ -56,6 +56,7 @@ def_op('UNARY_CONVERT', 13) ...@@ -56,6 +56,7 @@ def_op('UNARY_CONVERT', 13)
def_op('UNARY_INVERT', 15) def_op('UNARY_INVERT', 15)
def_op('LIST_APPEND', 18)
def_op('BINARY_POWER', 19) def_op('BINARY_POWER', 19)
def_op('BINARY_MULTIPLY', 20) def_op('BINARY_MULTIPLY', 20)
......
...@@ -12,6 +12,10 @@ What's New in Python 2.4 alpha 1? ...@@ -12,6 +12,10 @@ What's New in Python 2.4 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Implemented a newcode opcode, LIST_APPEND, that simplifies
the generated bytecode for list comprehensions and further
improves their performance (about 35%).
- Implemented rich comparisons for floats, which seems to make - Implemented rich comparisons for floats, which seems to make
comparisons involving NaNs somewhat less surprising when the comparisons involving NaNs somewhat less surprising when the
underlying C compiler actually implements C99 semantics. underlying C compiler actually implements C99 semantics.
......
...@@ -1225,6 +1225,15 @@ eval_frame(PyFrameObject *f) ...@@ -1225,6 +1225,15 @@ eval_frame(PyFrameObject *f)
if (x != NULL) continue; if (x != NULL) continue;
break; break;
case LIST_APPEND:
w = POP();
v = POP();
err = PyList_Append(v, w);
Py_DECREF(v);
Py_DECREF(w);
if (err == 0) continue;
break;
case INPLACE_POWER: case INPLACE_POWER:
w = POP(); w = POP();
v = TOP(); v = TOP();
......
...@@ -1552,8 +1552,7 @@ com_list_iter(struct compiling *c, ...@@ -1552,8 +1552,7 @@ com_list_iter(struct compiling *c,
com_addop_varname(c, VAR_LOAD, t); com_addop_varname(c, VAR_LOAD, t);
com_push(c, 1); com_push(c, 1);
com_node(c, e); com_node(c, e);
com_addoparg(c, CALL_FUNCTION, 1); com_addbyte(c, LIST_APPEND);
com_addbyte(c, POP_TOP);
com_pop(c, 2); com_pop(c, 2);
} }
} }
...@@ -1569,7 +1568,6 @@ com_list_comprehension(struct compiling *c, node *n) ...@@ -1569,7 +1568,6 @@ com_list_comprehension(struct compiling *c, node *n)
com_addoparg(c, BUILD_LIST, 0); com_addoparg(c, BUILD_LIST, 0);
com_addbyte(c, DUP_TOP); /* leave the result on the stack */ com_addbyte(c, DUP_TOP); /* leave the result on the stack */
com_push(c, 2); com_push(c, 2);
com_addop_name(c, LOAD_ATTR, "append");
com_addop_varname(c, VAR_STORE, tmpname); com_addop_varname(c, VAR_STORE, tmpname);
com_pop(c, 1); com_pop(c, 1);
com_list_for(c, CHILD(n, 1), CHILD(n, 0), tmpname); com_list_for(c, CHILD(n, 1), CHILD(n, 0), tmpname);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment