Commit dc63fb0e authored by Raymond Hettinger's avatar Raymond Hettinger

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).
parent 9bb2abde
...@@ -715,6 +715,7 @@ listextend(PyListObject *self, PyObject *b) ...@@ -715,6 +715,7 @@ listextend(PyListObject *self, PyObject *b)
int n; /* guess for size of b */ int n; /* guess for size of b */
int mn; /* m + n */ int mn; /* m + n */
int i; int i;
PyObject *(*iternext)(PyObject *);
/* Special cases: /* Special cases:
1) lists and tuples which can use PySequence_Fast ops 1) lists and tuples which can use PySequence_Fast ops
...@@ -732,6 +733,7 @@ listextend(PyListObject *self, PyObject *b) ...@@ -732,6 +733,7 @@ listextend(PyListObject *self, PyObject *b)
it = PyObject_GetIter(b); it = PyObject_GetIter(b);
if (it == NULL) if (it == NULL)
return NULL; return NULL;
iternext = *it->ob_type->tp_iternext;
/* Guess a result list size. */ /* Guess a result list size. */
n = PyObject_Size(b); n = PyObject_Size(b);
...@@ -747,10 +749,14 @@ listextend(PyListObject *self, PyObject *b) ...@@ -747,10 +749,14 @@ listextend(PyListObject *self, PyObject *b)
/* Run iterator to exhaustion. */ /* Run iterator to exhaustion. */
for (i = m; ; i++) { for (i = m; ; i++) {
PyObject *item = PyIter_Next(it); PyObject *item = iternext(it);
if (item == NULL) { if (item == NULL) {
if (PyErr_Occurred()) if (PyErr_Occurred()) {
goto error; if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
goto error;
}
break; break;
} }
if (i < mn) if (i < mn)
......
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