Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4fa58bf

Browse files
committed
Restore dicts' tp_compare slot, and change dict_richcompare to say it
doesn't know how to do LE, LT, GE, GT. dict_richcompare can't do the latter any faster than dict_compare can. More importantly, for cmp(dict1, dict2), Python *first* tries rich compares with EQ, LT, and GT one at a time, even if the tp_compare slot is defined, and dict_richcompare called dict_compare for the latter two because it couldn't do them itself. The result was a lot of wasted calls to dict_compare. Now dict_richcompare gives up at once the times Python calls it with LT and GT from try_rich_to_3way_compare(), and dict_compare is called only once (when Python gets around to trying the tp_compare slot). Continued mystery: despite that this cut the number of calls to dict_compare approximately in half in test_mutants.py, the latter still runs amazingly slowly. Running under the debugger doesn't show excessive activity in the dict comparison code anymore, so I'm guessing the culprit is somewhere else -- but where? Perhaps in the element (key/value) comparison code? We clearly spend a lot of time figuring out how to compare things.
1 parent 4c02fec commit 4fa58bf

1 file changed

Lines changed: 3 additions & 15 deletions

File tree

Objects/dictobject.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,20 +1160,8 @@ dict_richcompare(PyObject *v, PyObject *w, int op)
11601160
return NULL;
11611161
res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
11621162
}
1163-
else {
1164-
cmp = dict_compare((dictobject *)v, (dictobject *)w);
1165-
if (cmp < 0 && PyErr_Occurred())
1166-
return NULL;
1167-
switch (op) {
1168-
case Py_LT: cmp = cmp < 0; break;
1169-
case Py_LE: cmp = cmp <= 0; break;
1170-
case Py_GT: cmp = cmp > 0; break;
1171-
case Py_GE: cmp = cmp >= 0; break;
1172-
default:
1173-
assert(!"op unexpected");
1174-
}
1175-
res = cmp ? Py_True : Py_False;
1176-
}
1163+
else
1164+
res = Py_NotImplemented;
11771165
Py_INCREF(res);
11781166
return res;
11791167
}
@@ -1541,7 +1529,7 @@ PyTypeObject PyDict_Type = {
15411529
(printfunc)dict_print, /* tp_print */
15421530
(getattrfunc)dict_getattr, /* tp_getattr */
15431531
0, /* tp_setattr */
1544-
0, /* tp_compare */
1532+
(cmpfunc)dict_compare, /* tp_compare */
15451533
(reprfunc)dict_repr, /* tp_repr */
15461534
0, /* tp_as_number */
15471535
&dict_as_sequence, /* tp_as_sequence */

0 commit comments

Comments
 (0)