[Python-checkins] r59553 - in python/trunk: Include/dictobject.h Lib/opcode.py Misc/NEWS Objects/dictobject.c Python/ceval.c Python/compile.c
raymond.hettinger
python-checkins at python.org
Tue Dec 18 22:24:09 CET 2007
Author: raymond.hettinger
Date: Tue Dec 18 22:24:09 2007
New Revision: 59553
Modified:
python/trunk/Include/dictobject.h
python/trunk/Lib/opcode.py
python/trunk/Misc/NEWS
python/trunk/Objects/dictobject.c
python/trunk/Python/ceval.c
python/trunk/Python/compile.c
Log:
Give meaning to the oparg for BUILD_MAP: estimated size of the dictionary.
Allows dictionaries to be pre-sized (upto 255 elements) saving time lost
to re-sizes with their attendant mallocs and re-insertions.
Has zero effect on small dictionaries (5 elements or fewer), a slight
benefit for dicts upto 22 elements (because they had to resize once
anyway), and more benefit for dicts upto 255 elements (saving multiple
resizes during the build-up and reducing the number of collisions on
the first insertions). Beyond 255 elements, there is no addional benefit.
Modified: python/trunk/Include/dictobject.h
==============================================================================
--- python/trunk/Include/dictobject.h (original)
+++ python/trunk/Include/dictobject.h Tue Dec 18 22:24:09 2007
@@ -110,6 +110,7 @@
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash);
+PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
Modified: python/trunk/Lib/opcode.py
==============================================================================
--- python/trunk/Lib/opcode.py (original)
+++ python/trunk/Lib/opcode.py Tue Dec 18 22:24:09 2007
@@ -139,7 +139,7 @@
name_op('LOAD_NAME', 101) # Index in name list
def_op('BUILD_TUPLE', 102) # Number of tuple items
def_op('BUILD_LIST', 103) # Number of list items
-def_op('BUILD_MAP', 104) # Always zero for now
+def_op('BUILD_MAP', 104) # Number of dict entries (upto 255)
name_op('LOAD_ATTR', 105) # Index in name list
def_op('COMPARE_OP', 106) # Comparison operator
hascompare.append(106)
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Tue Dec 18 22:24:09 2007
@@ -12,6 +12,10 @@
Core and builtins
-----------------
+- Compiler now generates simpler and faster code for dictionary literals.
+ The oparg for BUILD_MAP now indicates an estimated dictionary size.
+ There is a new opcode, STORE_MAP, for adding entries to the dictionary.
+
- Issue #1638: %zd configure test fails on Linux
- Issue #1620: New property decorator syntax was modifying the decorator
Modified: python/trunk/Objects/dictobject.c
==============================================================================
--- python/trunk/Objects/dictobject.c (original)
+++ python/trunk/Objects/dictobject.c Tue Dec 18 22:24:09 2007
@@ -549,6 +549,23 @@
return 0;
}
+/* Create a new dictionary pre-sized to hold an estimated number of elements.
+ Underestimates are okay because the dictionary will resize as necessary.
+ Overestimates just mean the dictionary will be more sparse than usual.
+*/
+
+PyObject *
+_PyDict_NewPresized(Py_ssize_t minused)
+{
+ PyObject *op = PyDict_New();
+
+ if (minused>5 && op != NULL && dictresize((PyDictObject *)op, minused) == -1) {
+ Py_DECREF(op);
+ return NULL;
+ }
+ return op;
+}
+
/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
* that may occur (originally dicts supported only string keys, and exceptions
* weren't possible). So, while the original intent was that a NULL return
Modified: python/trunk/Python/ceval.c
==============================================================================
--- python/trunk/Python/ceval.c (original)
+++ python/trunk/Python/ceval.c Tue Dec 18 22:24:09 2007
@@ -1997,7 +1997,7 @@
break;
case BUILD_MAP:
- x = PyDict_New();
+ x = _PyDict_NewPresized((Py_ssize_t)oparg);
PUSH(x);
if (x != NULL) continue;
break;
Modified: python/trunk/Python/compile.c
==============================================================================
--- python/trunk/Python/compile.c (original)
+++ python/trunk/Python/compile.c Tue Dec 18 22:24:09 2007
@@ -2922,11 +2922,9 @@
case IfExp_kind:
return compiler_ifexp(c, e);
case Dict_kind:
- /* XXX get rid of arg? */
- ADDOP_I(c, BUILD_MAP, 0);
n = asdl_seq_LEN(e->v.Dict.values);
- /* We must arrange things just right for STORE_SUBSCR.
- It wants the stack to look like (value) (dict) (key) */
+ ADDOP_I(c, BUILD_MAP, (n>255 ? 255 : n));
+ n = asdl_seq_LEN(e->v.Dict.values);
for (i = 0; i < n; i++) {
VISIT(c, expr,
(expr_ty)asdl_seq_GET(e->v.Dict.values, i));
More information about the Python-checkins
mailing list