summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-07-11 21:46:16 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-07-11 21:46:16 (GMT)
commitf2a0473350d91065cb1ac14ca4b55d56eea1ed38 (patch)
tree2e7aa3a55a29a8883ccbb629142dbe7eb0917321
parent1808fbc46daae1e8a95359716e48b3f3a927c203 (diff)
downloadcpython-f2a0473350d91065cb1ac14ca4b55d56eea1ed38.zip
cpython-f2a0473350d91065cb1ac14ca4b55d56eea1ed38.tar.gz
cpython-f2a0473350d91065cb1ac14ca4b55d56eea1ed38.tar.bz2
docompare(): Use PyTuple_New instead of Py_BuildValue to build compare's
arg tuple. This was suggested on c.l.py but afraid I can't find the msg again for proper attribution. For list.sort(cmp) where list is a list of random ints, and cmp is __builtin__.cmp, this yields an overall 50-60% speedup on my Win2K box. Of course this is a best case, because the overhead of calling cmp relative to the cost of actually comparing two ints is at an extreme. Nevertheless it's huge bang for the buck. An additionak 20-30% can be bought by making the arg tuple an immortal static (avoiding all but "the first" PyTuple_New), but that's tricky to make correct since docompare needs to be reentrant. So this picks the cherry and leaves the pits for Fred <wink>. Note that this makes no difference to the list.sort() case; an arg tuple gets built only if the user specifies an explicit sort function.
-rw-r--r--Objects/listobject.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 77349bb..36aa7f3 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -756,7 +756,8 @@ listpop(PyListObject *self, PyObject *args)
static int
docompare(PyObject *x, PyObject *y, PyObject *compare)
{
- PyObject *args, *res;
+ PyObject *res;
+ PyObject *args;
int i;
if (compare == NULL) {
@@ -772,9 +773,13 @@ docompare(PyObject *x, PyObject *y, PyObject *compare)
return -i;
}
- args = Py_BuildValue("(OO)", x, y);
+ args = PyTuple_New(2);
if (args == NULL)
return CMPERROR;
+ Py_INCREF(x);
+ Py_INCREF(y);
+ PyTuple_SET_ITEM(args, 0, x);
+ PyTuple_SET_ITEM(args, 1, y);
res = PyEval_CallObject(compare, args);
Py_DECREF(args);
if (res == NULL)