Commit b7fff59c authored by Guido van Rossum's avatar Guido van Rossum

Improve performance of built-in any()/all() by avoiding PyIter_Next() --

using a trick found in ifilter().
Feel free to backport to 2.5.
parent 3ebe0f14
...@@ -78,13 +78,19 @@ static PyObject * ...@@ -78,13 +78,19 @@ static PyObject *
builtin_all(PyObject *self, PyObject *v) builtin_all(PyObject *self, PyObject *v)
{ {
PyObject *it, *item; PyObject *it, *item;
PyObject *(*iternext)(PyObject *);
int cmp;
it = PyObject_GetIter(v); it = PyObject_GetIter(v);
if (it == NULL) if (it == NULL)
return NULL; return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
while ((item = PyIter_Next(it)) != NULL) { for (;;) {
int cmp = PyObject_IsTrue(item); item = iternext(it);
if (item == NULL)
break;
cmp = PyObject_IsTrue(item);
Py_DECREF(item); Py_DECREF(item);
if (cmp < 0) { if (cmp < 0) {
Py_DECREF(it); Py_DECREF(it);
...@@ -96,8 +102,12 @@ builtin_all(PyObject *self, PyObject *v) ...@@ -96,8 +102,12 @@ builtin_all(PyObject *self, PyObject *v)
} }
} }
Py_DECREF(it); Py_DECREF(it);
if (PyErr_Occurred()) if (PyErr_Occurred()) {
return NULL; if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL;
}
Py_RETURN_TRUE; Py_RETURN_TRUE;
} }
...@@ -110,13 +120,19 @@ static PyObject * ...@@ -110,13 +120,19 @@ static PyObject *
builtin_any(PyObject *self, PyObject *v) builtin_any(PyObject *self, PyObject *v)
{ {
PyObject *it, *item; PyObject *it, *item;
PyObject *(*iternext)(PyObject *);
int cmp;
it = PyObject_GetIter(v); it = PyObject_GetIter(v);
if (it == NULL) if (it == NULL)
return NULL; return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
while ((item = PyIter_Next(it)) != NULL) { for (;;) {
int cmp = PyObject_IsTrue(item); item = iternext(it);
if (item == NULL)
break;
cmp = PyObject_IsTrue(item);
Py_DECREF(item); Py_DECREF(item);
if (cmp < 0) { if (cmp < 0) {
Py_DECREF(it); Py_DECREF(it);
...@@ -128,8 +144,12 @@ builtin_any(PyObject *self, PyObject *v) ...@@ -128,8 +144,12 @@ builtin_any(PyObject *self, PyObject *v)
} }
} }
Py_DECREF(it); Py_DECREF(it);
if (PyErr_Occurred()) if (PyErr_Occurred()) {
return NULL; if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL;
}
Py_RETURN_FALSE; Py_RETURN_FALSE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment