On Sat, 13 Jan 2007 10:04:17 -0600, Paul McGuire wrote: > Just a side note on writing these comparison operators. I remember when > learning Java that this was really the first time I spent so much time > reading about testing-for-identity vs. testing-for-equality. The Java > conventional practice at the time was to begin each test-for-equality method > by testing to see if an object were being compared against itself, and if > so, cut to the chase and return True (and the converse for an inequality > comparison). The idea behind this was that there were ostensibly many times > in code where an object was being compared against itself (not so much in an > explicit "if x==x" but in implicit tests such as list searching and > filtering), and this upfront test-for-identity, being very fast, could > short-circuit an otherwise needless comparison. > > In Python, this would look like: > > class Parrot: > def __eq__(self, other): > return self is other or self.plumage() == other.plumage()
[snip] Surely this is only worth doing if the comparison is expensive? Testing beats intuition, so let's find out... class Compare: def __init__(self, x): self.x = x def __eq__(self, other): return self.x == other.x class CompareWithIdentity: def __init__(self, x): self.x = x def __eq__(self, other): return self is other or self.x == other.x Here's the timing results without the identity test: >>> import timeit >>> x = Compare(1); y = Compare(1) >>> timeit.Timer("x = x", "from __main__ import x,y").repeat() [0.20771503448486328, 0.16396403312683105, 0.16507196426391602] >>> timeit.Timer("x = y", "from __main__ import x,y").repeat() [0.20918107032775879, 0.16187810897827148, 0.16351795196533203] And with the identity test: >>> x = CompareWithIdentity(1); y = CompareWithIdentity(1) >>> timeit.Timer("x = x", "from __main__ import x,y").repeat() [0.20761799812316895, 0.16907095909118652, 0.16420602798461914] >>> timeit.Timer("x = y", "from __main__ import x,y").repeat() [0.2090909481048584, 0.1968839168548584, 0.16479206085205078] Anyone want to argue that this is a worthwhile optimization? :) > On the other hand, I haven't seen this idiom in any Python code that I've > read, and I wonder if this was just a coding fad of the time. > > Still, in cases such as Steven's Aardark class, it might be worth > bypassing something that calls lots_of_work if you tested first to see > if self is not other. The comparison itself would have to be quite expensive to make it worth the extra code. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list