[Python-checkins] cpython (3.3): Issue #18594: Fix the fast path for collections.Counter().
raymond.hettinger
python-checkins at python.org
Tue Oct 1 10:01:15 CEST 2013
http://hg.python.org/cpython/rev/6aef095fdb30
changeset: 85909:6aef095fdb30
branch: 3.3
parent: 85907:0e204fbb0b08
user: Raymond Hettinger <python at rcn.com>
date: Tue Oct 01 00:55:43 2013 -0700
summary:
Issue #18594: Fix the fast path for collections.Counter().
The path wasn't being taken due to an over-restrictive type check.
files:
Include/object.h | 1 +
Misc/NEWS | 3 +++
Modules/_collectionsmodule.c | 16 +++++++++++++++-
Objects/typeobject.c | 5 +----
4 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/Include/object.h b/Include/object.h
--- a/Include/object.h
+++ b/Include/object.h
@@ -482,6 +482,7 @@
PyObject *, PyObject *);
#ifndef Py_LIMITED_API
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
+PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *);
PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
#endif
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -74,6 +74,9 @@
- Issue #12641: Avoid passing "-mno-cygwin" to the mingw32 compiler, except
when necessary. Patch by Oscar Benjamin.
+- Issue #18594: The fast path for collections.Counter() was never taken
+ due to an over-restrictive type check.
+
- Properly initialize all fields of a SSL object after allocation.
- Issue #4366: Fix building extensions on all platforms when --enable-shared
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -1689,10 +1689,16 @@
static PyObject *
_count_elements(PyObject *self, PyObject *args)
{
+ _Py_IDENTIFIER(__getitem__);
+ _Py_IDENTIFIER(__setitem__);
PyObject *it, *iterable, *mapping, *oldval;
PyObject *newval = NULL;
PyObject *key = NULL;
PyObject *one = NULL;
+ PyObject *mapping_getitem;
+ PyObject *mapping_setitem;
+ PyObject *dict_getitem;
+ PyObject *dict_setitem;
if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable))
return NULL;
@@ -1707,7 +1713,15 @@
return NULL;
}
- if (PyDict_CheckExact(mapping)) {
+ mapping_getitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___getitem__);
+ dict_getitem = _PyType_LookupId(&PyDict_Type, &PyId___getitem__);
+ mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__);
+ dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
+
+ if (mapping_getitem != NULL &&
+ mapping_getitem == dict_getitem &&
+ mapping_setitem != NULL &&
+ mapping_setitem == dict_setitem) {
while (1) {
key = PyIter_Next(it);
if (key == NULL)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -50,9 +50,6 @@
_Py_IDENTIFIER(__new__);
static PyObject *
-_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name);
-
-static PyObject *
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
unsigned int
@@ -2589,7 +2586,7 @@
return res;
}
-static PyObject *
+PyObject *
_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name)
{
PyObject *oname;
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list