Mercurial > cpython-lru_cache-weakref
diff Python/bltinmodule.c @ 44367:eaefb93b5ed4 legacy-trunk
Improve performance of built-in any()/all() by avoiding PyIter_Next() --
using a trick found in ifilter().
Feel free to backport to 2.5.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Thu, 20 Dec 2007 23:48:28 +0000 |
| parents | 9a976a6ee936 |
| children | 4f9723d9ca32 |
line wrap: on
line diff
--- a/Python/bltinmodule.c Thu Dec 20 21:03:02 2007 +0000 +++ b/Python/bltinmodule.c Thu Dec 20 23:48:28 2007 +0000 @@ -78,13 +78,19 @@ builtin_all(PyObject *self, PyObject *v) { PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + int cmp; it = PyObject_GetIter(v); if (it == NULL) return NULL; + iternext = *Py_TYPE(it)->tp_iternext; - while ((item = PyIter_Next(it)) != NULL) { - int cmp = PyObject_IsTrue(item); + for (;;) { + item = iternext(it); + if (item == NULL) + break; + cmp = PyObject_IsTrue(item); Py_DECREF(item); if (cmp < 0) { Py_DECREF(it); @@ -96,8 +102,12 @@ } } Py_DECREF(it); - if (PyErr_Occurred()) - return NULL; + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + return NULL; + } Py_RETURN_TRUE; } @@ -110,13 +120,19 @@ builtin_any(PyObject *self, PyObject *v) { PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + int cmp; it = PyObject_GetIter(v); if (it == NULL) return NULL; + iternext = *Py_TYPE(it)->tp_iternext; - while ((item = PyIter_Next(it)) != NULL) { - int cmp = PyObject_IsTrue(item); + for (;;) { + item = iternext(it); + if (item == NULL) + break; + cmp = PyObject_IsTrue(item); Py_DECREF(item); if (cmp < 0) { Py_DECREF(it); @@ -128,8 +144,12 @@ } } Py_DECREF(it); - if (PyErr_Occurred()) - return NULL; + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + return NULL; + } Py_RETURN_FALSE; }
