Re: Speed of str(positive_integer)..

From: Tim Peters (tim.peters_at_gmail.com)
Date: 07/31/04


Date: Sat, 31 Jul 2004 05:28:38 -0400
To: python-list@python.org


[Tony Meyer]
> ...
> It does seem odd that "r,q = divmod(b,c)" is slower than "r = b//c;q =
> b-r*c" (or "r = b//c;q=b%c", which is better), but timeit shows that it is
> (with Python 2.3.4). I suppose this is the penalty for the additional work
> that divmod does with checking signs and so on.

Integer // and integer % both work by invoking integer divmod
(i_divmod() in intobject.c) under the covers. // returns the first
result, and % returns the second. So the faster ways actually compute
both the quotient and the remainder twice!

Looking up "divmod" is part of reason; that has to fail to find
"divmod" in the globals first, and then succeed finding "divmod" in
the builtins.

But that's not the bulk of the reason. The primary reason calling
divmod is slower is the need to allocate and fill in divmod's 2-tuple
result. For ints, that can be more expensive than the actual
arithmetic.

If you're using long ints instead, the time to lookup "divmod" and
build the tuple can be trivial compared to the time to do the actual
arithmetic, and then divmod is indeed twice as fast as doing it "the
fast" way <wink>; e.g.,

$ timeit.py -s a=10**300 -s b=2**100 divmod(a,b)
100000 loops, best of 3: 8.83 usec per loop

$ timeit.py -s a=10**300 -s b=2**100 a//b;a%b
100000 loops, best of 3: 17.1 usec per loop



Relevant Pages

  • Re: hashing mutable instances
    ... The reason this is done is because it's useful. ... 100000 loops, best of 3: 3.5 usec per loop ... Another good performance reason to make the class newstyle and thus ...
    (comp.lang.python)
  • Re: Do more imported objects affect performance
    ... reason is simple. ... Importing the module is actualy slower... ... 10000000 loops, best of 3: 0.0784 usec per loop ...
    (comp.lang.python)
  • Re: list.clear() missing?!?
    ... 100 loops, best of 3: ... addresses whether you comment or uncomment del ... (the reason is in the comment: ... 213 usec per loop ...
    (comp.lang.python)
  • Re: Using in with a Dict
    ... A little performance testing told me that has_key ... but the reason has_key is slower is almost certainly ... 10000 loops, best of 3: 102 usec per loop ...
    (comp.lang.python)