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 *
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 @@ builtin_all(PyObject *self, PyObject *v)
}
}
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 @@ static PyObject *
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 @@ builtin_any(PyObject *self, PyObject *v)
}
}
Py_DECREF(it);
if (PyErr_Occurred())
return NULL;
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL;
}
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