[Python-Dev] RE: Rich comparisons [Was] redefining is

Tim Peters tim.one at comcast.net
Sat Mar 20 00:35:06 EST 2004


[Tim]
>> Well, string_richcompare() takes that shortcut, so the advice is
>> good, but PyObject_RichCompare() doesn't in general
>> (PyObject_Compare() still does, but that's not triggered by '==').

[Raymond Hettinger]
> Hey, hey, this may be part of the answer to why my timings for
> equality testing using rich comparisions run so much slower than they
> do with PyObject_Compare().

Except I expect that depends on exactly what your timing tests compare.  A
special case for object identity isn't a pure win, since it slows every
non-identical case (by the time to determine they're not identical, and
branch over the early exit).

For strings specifically it appeared to be a win, because Python's
implementation works hard to create interned strings in common cases, and
does so largely so that this trick *can* pay off.

But for floats it's hard to imagine this special case wouldn't be a net
oss  -- Python almost never reuses float objects.

>>> float(0) is float(0)
False
>>>

> Fixing this would entail a change in semantics but would be worth it
> if we can all agree to it.
>
> Essentially, I would like to insert the following lines into
> PyObject_RichCompare():
>
> 	if (v == w) {
> 		if (op == Py_EQ)
> 			Py_RETURN_TRUE;
> 		else if (op == Py_NE)
> 			Py_RETURN_FALSE;
> 	}

Then, e.g., you make virtually all real-life float comparisons slower.

> The test suite runs fine, but it is possible that some existing class
> defines equality in a way that sometimes returns False even when given
> two identical objects.
>
> I think the change is worth it -- tests for equality are ubiquitous
> (and somewhat common) throughout the source.

It's not the number of equality tests that matter, it's the ratio of the
number of "==" and "!=" tests that actually compare identical comparands, to
the total number of all rich comparisons executed.  Besides the change to
semantics, the patch would be a speed loss for everything in the latter set
minus the former.




More information about the Python-Dev mailing list