]> granicus.if.org Git - python/commitdiff
Speed-up dictionary constructor by about 10%.
authorRaymond Hettinger <python@rcn.com>
Tue, 18 Dec 2007 18:26:18 +0000 (18:26 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 18 Dec 2007 18:26:18 +0000 (18:26 +0000)
New opcode, STORE_MAP saves the compiler from awkward stack manipulations
and specializes for dicts using PyDict_SetItem instead of PyObject_SetItem.

Old disassembly:
              0 BUILD_MAP                0
              3 DUP_TOP
              4 LOAD_CONST               1 (1)
              7 ROT_TWO
              8 LOAD_CONST               2 ('x')
             11 STORE_SUBSCR
             12 DUP_TOP
             13 LOAD_CONST               3 (2)
             16 ROT_TWO
             17 LOAD_CONST               4 ('y')
             20 STORE_SUBSCR

New disassembly:
              0 BUILD_MAP                0
              3 LOAD_CONST               1 (1)
              6 LOAD_CONST               2 ('x')
              9 STORE_MAP
             10 LOAD_CONST               3 (2)
             13 LOAD_CONST               4 ('y')
             16 STORE_MAP

Include/opcode.h
Lib/opcode.py
Python/ceval.c
Python/compile.c
Python/import.c

index 28163693fe937225508bc8d0972c082979c6960b..9f20b56d6851e64846d9481e7961a918925f1904 100644 (file)
@@ -45,6 +45,7 @@ extern "C" {
 #define DELETE_SLICE   50
 /* Also uses 51-53 */
 
+#define STORE_MAP      54
 #define INPLACE_ADD    55
 #define INPLACE_SUBTRACT       56
 #define INPLACE_MULTIPLY       57
index 095ca42ec01a899e0870ec467a567548279b93ba..c3457d014ae1c7ed213da76c955620f80c706908 100644 (file)
@@ -85,6 +85,7 @@ def_op('DELETE_SLICE+1', 51)
 def_op('DELETE_SLICE+2', 52)
 def_op('DELETE_SLICE+3', 53)
 
+def_op('STORE_MAP', 54)
 def_op('INPLACE_ADD', 55)
 def_op('INPLACE_SUBTRACT', 56)
 def_op('INPLACE_MULTIPLY', 57)
index d74d0179963c6530a832e8c0fd0d4376bdff7c8b..1af998d77781c5701f1fc2a188251c0131f607fd 100644 (file)
@@ -2002,6 +2002,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                        if (x != NULL) continue;
                        break;
 
+               case STORE_MAP:
+                       w = TOP();     /* key */
+                       u = SECOND();  /* value */
+                       v = THIRD();   /* dict */
+                       STACKADJ(-2);
+                       assert (PyDict_CheckExact(v));
+                       err = PyDict_SetItem(v, w, u);  /* v[w] = u */
+                       Py_DECREF(u);
+                       Py_DECREF(w);
+                       if (err == 0) continue;
+                       break;
+
                case LOAD_ATTR:
                        w = GETITEM(names, oparg);
                        v = TOP();
index 193d52076ab0b591fd92f386e01f1ba97627420a..3b0c53fb193c53ef8df987c2462bf79f340d8772 100644 (file)
@@ -729,6 +729,8 @@ opcode_stack_effect(int opcode, int oparg)
                        return -1;
                case STORE_SUBSCR:
                        return -3;
+               case STORE_MAP:
+                       return -2;
                case DELETE_SUBSCR:
                        return -2;
 
@@ -2926,13 +2928,11 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
                /* We must arrange things just right for STORE_SUBSCR.
                   It wants the stack to look like (value) (dict) (key) */
                for (i = 0; i < n; i++) {
-                       ADDOP(c, DUP_TOP);
                        VISIT(c, expr, 
                                (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
-                       ADDOP(c, ROT_TWO);
                        VISIT(c, expr, 
                                (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
-                       ADDOP(c, STORE_SUBSCR);
+                       ADDOP(c, STORE_MAP);
                }
                break;
        case ListComp_kind:
index bf2799d55403b0200d8f117ffeea7ef359e50392..bcae9b2eed14d985bf0a71a8e080db31b8201cb5 100644 (file)
@@ -66,10 +66,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
        Python 2.5c1: 62121 (fix wrong lnotab with for loops and
                                    storing constants that should have been removed)
        Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
-       Python 2.6a0: 62141 (peephole optimizations)
+       Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)
 .
 */
-#define MAGIC (62141 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (62151 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the