Issue 31410: int.repr() is slower than repr() (original) (raw)

Following the StackOverflow question [1].

Calling repr() is faster than calling unbound method repr(). This looks strange at first glance because it is obvious that repr() is implemented via calling repr().

$ ./python -m timeit "''.join(map(repr, range(10000)))" 500 loops, best of 5: 809 usec per loop

$ ./python -m timeit "''.join(map(int.repr, range(10000)))" 200 loops, best of 5: 1.27 msec per loop

Actually repr() just called the tp_repr slot, while calling int.repr passes through many intermediate layers.

Proposed PR gets rid of a half of the overhead. It avoids creating and calling an itermediate function object. The result still is slower then calling repr().

$ ./python -m timeit "''.join(map(int.repr, range(10000)))" 200 loops, best of 5: 1.01 msec per loop

The PR also speeds up calling classmethod descriptors.

$ ./python -m timeit -s "cm = bytes.fromhex; args = [('',)]*10000; from itertools import starmap" -- "b''.join(starmap(cm, args))" 500 loops, best of 5: 515 usec per loop

$ ./python -m timeit -s "cm = bytes.dict['fromhex']; args = [(bytes, '')]*10000; from itertools import starmap" -- "b''.join(starmap(cm, args))" 500 loops, best of 5: 704 usec per loop

Patched:

$ ./python -m timeit -s "cm = bytes.dict['fromhex']; args = [(bytes, '')]*10000; from itertools import starmap" -- "b''.join(starmap(cm, args))" 500 loops, best of 5: 598 usec per loop

[1] https://stackoverflow.com/questions/45376719/why-is-reprint-faster-than-strint