summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-16 07:04:56 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-16 07:04:56 (GMT)
commitc7903a13d2dc58d2f239a4d3bb29703199b450e4 (patch)
treec58b263f9df73631be99d1e8555c93a6020581c5 /Python
parent8e829200b1ac79750224563331032de031b76288 (diff)
downloadcpython-c7903a13d2dc58d2f239a4d3bb29703199b450e4.zip
cpython-c7903a13d2dc58d2f239a4d3bb29703199b450e4.tar.gz
cpython-c7903a13d2dc58d2f239a4d3bb29703199b450e4.tar.bz2
A nice little speed-up for filter():
- Use PyObject_Call() instead of PyEval_CallObject(), saves several layers of calls and checks. - Pre-allocate the argument tuple rather than calling Py_BuildValue() each time round the loop. - For filter(None, seq), avoid an INCREF and a DECREF.
Diffstat (limited to 'Python')
-rw-r--r--Python/bltinmodule.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 83931d9..660abeb 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -122,7 +122,7 @@ Note that classes are callable, as are instances with a __call__() method.");
static PyObject *
builtin_filter(PyObject *self, PyObject *args)
{
- PyObject *func, *seq, *result, *it;
+ PyObject *func, *seq, *result, *it, *arg;
int len; /* guess for result list size */
register int j;
@@ -151,6 +151,11 @@ builtin_filter(PyObject *self, PyObject *args)
if (len < 0)
len = 8; /* arbitrary */
+ /* Pre-allocate argument list tuple. */
+ arg = PyTuple_New(1);
+ if (arg == NULL)
+ goto Fail_arg;
+
/* Get a result list. */
if (PyList_Check(seq) && seq->ob_refcnt == 1) {
/* Eww - can modify the list in-place. */
@@ -166,7 +171,7 @@ builtin_filter(PyObject *self, PyObject *args)
/* Build the result list. */
j = 0;
for (;;) {
- PyObject *item, *good;
+ PyObject *item;
int ok;
item = PyIter_Next(it);
@@ -177,24 +182,20 @@ builtin_filter(PyObject *self, PyObject *args)
}
if (func == Py_None) {
- good = item;
- Py_INCREF(good);
+ ok = PyObject_IsTrue(item);
}
else {
- PyObject *arg = Py_BuildValue("(O)", item);
- if (arg == NULL) {
- Py_DECREF(item);
- goto Fail_result_it;
- }
- good = PyEval_CallObject(func, arg);
- Py_DECREF(arg);
+ PyObject *good;
+ PyTuple_SET_ITEM(arg, 0, item);
+ good = PyObject_Call(func, arg, NULL);
+ PyTuple_SET_ITEM(arg, 0, NULL);
if (good == NULL) {
Py_DECREF(item);
goto Fail_result_it;
}
+ ok = PyObject_IsTrue(good);
+ Py_DECREF(good);
}
- ok = PyObject_IsTrue(good);
- Py_DECREF(good);
if (ok) {
if (j < len)
PyList_SET_ITEM(result, j, item);
@@ -216,12 +217,15 @@ builtin_filter(PyObject *self, PyObject *args)
goto Fail_result_it;
Py_DECREF(it);
+ Py_DECREF(arg);
return result;
Fail_result_it:
Py_DECREF(result);
Fail_it:
Py_DECREF(it);
+Fail_arg:
+ Py_DECREF(arg);
return NULL;
}