From: Raymond Hettinger Date: Thu, 11 Mar 2004 09:48:18 +0000 (+0000) Subject: Now that list.extend() is at the root of many list operations, it becomes X-Git-Tag: v2.4a1~718 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=57c4542bcdd0bcf3bb18911f5cac8f7ccfb4c85f;p=python Now that list.extend() is at the root of many list operations, it becomes worth it to in-line the call to PyIter_Next(). Saves another 15% on most list operations that acceptable a general iterable argument (such as the list constructor). --- diff --git a/Objects/listobject.c b/Objects/listobject.c index ed6ed3e561..2f2097d0d5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -715,6 +715,7 @@ listextend(PyListObject *self, PyObject *b) int n; /* guess for size of b */ int mn; /* m + n */ int i; + PyObject *(*iternext)(PyObject *); /* Special cases: 1) lists and tuples which can use PySequence_Fast ops @@ -732,6 +733,7 @@ listextend(PyListObject *self, PyObject *b) it = PyObject_GetIter(b); if (it == NULL) return NULL; + iternext = *it->ob_type->tp_iternext; /* Guess a result list size. */ n = PyObject_Size(b); @@ -747,10 +749,14 @@ listextend(PyListObject *self, PyObject *b) /* Run iterator to exhaustion. */ for (i = m; ; i++) { - PyObject *item = PyIter_Next(it); + PyObject *item = iternext(it); if (item == NULL) { - if (PyErr_Occurred()) - goto error; + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + goto error; + } break; } if (i < mn)