Steven D'Aprano <[EMAIL PROTECTED]> writes: > On Sat, 22 Nov 2008 09:10:04 +0000, Arnaud Delobelle wrote: > >> That's not surprising. You're measuring the wrong things. If you read >> what I wrote, you'll see that I'm talking about Fraction.__gt__ being >> slower (as it is defined in terms of Fraction.__eq__ and >> Fraction.__lt__) using when my 'totally_ordered' decorator. >> >> I haven't done any tests but as Fraction.__gt__ calls *both* >> Fraction.__eq__ and Fraction.__lt__ it is obvious that it is going to be >> roughly twice as slow. > > > What's obvious to you and what's obvious to the Python VM are not > necessarily the same thing. I believe you are worrying about the wrong > thing.
All I was asserting was that using my decorator, Fraction.__gt__ would be roughly twice as slow as Fraction.__eq__ or Fraction.__lt__. I was not worried about it at all! Your tests below, although very interesting, don't shed any light on this. > (BTW, I think your earlier decorator had a bug, in that it failed to > define __ne__ but then called "self != other".) That would be true for Python 2.x but I'm explicitly writing code for Python 3 here, which, IIRC, infers != correctly when you define ==. I can't refer you to the docs because my internet access to some US sites seems to be partly broken ATM, but here's a simple example: Python 3.0rc1+ (py3k:66521, Sep 21 2008, 07:58:29) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> class A: ... def __init__(self): ... self ... >>> >>> class A: ... def __init__(self, x): ... self.x = x ... def __eq__(self, other): ... return self.x == other.x ... >>> a, b, c = A(1), A(1), A(2) >>> a==b, b==c, c==a (True, False, False) >>> a!=b, b!=c, c!=a (False, True, True) >>> > My tests suggest that relying on __cmp__ is nearly three times > *slower* than your decorated class, and around four times slower than > defining all the rich comparisons directly: > > $ python comparisons.py > Testing FractionCmp... 37.4376080036 > Testing FractionRichCmpDirect... 9.83379387856 > Testing FractionRichCmpIndirect... 16.152534008 > Testing FractionDecoratored... 13.2626030445 > > Test code follows. If I've made an error, please let me know. [snip test code] If anything these tests make a retroactive case for getting rid of __cmp__ as it seems really slow. Even FractionRichCmpIndirect (which is the same as applying my second totally_ordered decorator to FractionCmp) is almost twice as fast as FractionCmp. I would guess it is because when doing e.g. a < b The VM will first look for a.__lt__(b) and fail, wasting some time in the process. Then it would look for a.__cmp__(b) Whereas when __lt__ is explicitely defined, the first step always succeeds. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list