]> granicus.if.org Git - python/commitdiff
SF patch #910929: Optimize list comprehensions
authorRaymond Hettinger <python@rcn.com>
Sun, 7 Mar 2004 07:31:06 +0000 (07:31 +0000)
committerRaymond Hettinger <python@rcn.com>
Sun, 7 Mar 2004 07:31:06 +0000 (07:31 +0000)
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.

Doc/whatsnew/whatsnew24.tex
Include/opcode.h
Lib/opcode.py
Misc/NEWS
Python/ceval.c
Python/compile.c

index 24650fa5bc8b6fa240c6be1ae73792fb1b99aa70..2a323ff84e08bf52f6c7b6548f61d8d717f942f8 100644 (file)
@@ -288,6 +288,10 @@ yellow 5
   use as arguments to functionals:
   \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}
 
 The net result of the 2.4 optimizations is that Python 2.4 runs the
index 2f3dd04ba479182be3fc71445f6c422c3b2d1458..8df96b4f224fb2c3b27d4ac225def38df65e44c9 100644 (file)
@@ -21,6 +21,7 @@ extern "C" {
 
 #define UNARY_INVERT   15
 
+#define LIST_APPEND    18
 #define BINARY_POWER   19
 
 #define BINARY_MULTIPLY        20
index 39d4bd24ae6b39251f7f8778a0e72b53c878bff4..ae9f6ccf13f8219e16a7973f7b3e0356b70080ff 100644 (file)
@@ -56,6 +56,7 @@ def_op('UNARY_CONVERT', 13)
 
 def_op('UNARY_INVERT', 15)
 
+def_op('LIST_APPEND', 18)
 def_op('BINARY_POWER', 19)
 
 def_op('BINARY_MULTIPLY', 20)
index 72232c8de85bc792dab8702c42d80f44ab724325..f3554c389df3876d75860196071a7d4a0e759ec9 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.4 alpha 1?
 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
   comparisons involving NaNs somewhat less surprising when the
   underlying C compiler actually implements C99 semantics.
index 337184464f1334157acec97537de3707434716ae..b20934c0573712630ced018130bbd6fb53a20327 100644 (file)
@@ -1225,6 +1225,15 @@ eval_frame(PyFrameObject *f)
                        if (x != NULL) continue;
                        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:
                        w = POP();
                        v = TOP();
index 04d8b65f4b4ff5f311662f28482f7afafbe5f3a0..f58fb83efce916b9046ce2092056f5da7e321976 100644 (file)
@@ -1552,8 +1552,7 @@ com_list_iter(struct compiling *c,
                com_addop_varname(c, VAR_LOAD, t);
                com_push(c, 1);
                com_node(c, e);
-               com_addoparg(c, CALL_FUNCTION, 1);
-               com_addbyte(c, POP_TOP);
+               com_addbyte(c, LIST_APPEND);
                com_pop(c, 2);
        }
 }
@@ -1569,7 +1568,6 @@ com_list_comprehension(struct compiling *c, node *n)
        com_addoparg(c, BUILD_LIST, 0);
        com_addbyte(c, DUP_TOP); /* leave the result on the stack */
        com_push(c, 2);
-       com_addop_name(c, LOAD_ATTR, "append");
        com_addop_varname(c, VAR_STORE, tmpname);
        com_pop(c, 1);
        com_list_for(c, CHILD(n, 1), CHILD(n, 0), tmpname);