
On 7/21/2015 12:25 AM, Eric V. Smith wrote:
On 7/21/2015 12:02 AM, Alexander Belopolsky wrote:
On Mon, Jul 20, 2015 at 11:35 PM, Tim Peters <tim.peters@gmail.com <mailto:tim.peters@gmail.com>> wrote:
>>> dis(f) 2 0 LOAD_CONST 3 ('2') 3 RETURN_VALUE
That is, the peephole optimizer got rid of "%d" % 2 entirely, replacing it with the string constant "2". So, in all, it's more surprising that it takes so long to load a constant ;-)
Hmm. I stand corrected:
$ python3 -mtimeit -s "a=2" "'%s' % a" 10000000 loops, best of 3: 0.124 usec per loop $ python3 -mtimeit -s "a=2" "'{}'.format(a)" 1000000 loops, best of 3: 0.215 usec per loop
it is 2x rather than 20x speed difference.
The last time I looked at this, the performance difference was the lookup of "format" on a string object. Although maybe that's not true, and the problem is really function call overhead:
$ python3 -mtimeit -s 'a=2' 'f="{}".format' 'f(a)' 1000000 loops, best of 3: 0.227 usec per loop $ python3 -mtimeit -s "a=2" "'%s' % a" 10000000 loops, best of 3: 0.126 usec per loop
Oops, that should have been: $ python3 -mtimeit -s 'a=2; f="{}".format' 'f(a)' 1000000 loops, best of 3: 0.19 usec per loop $ python3 -mtimeit -s "a=2" "'%s' % a" 10000000 loops, best of 3: 0.138 usec per loop So, about 40% slower if you can get rid of the .format lookup, which we can do with f-strings. Because it's more flexible, .format is just never going to be as fast as %-formatting. But there's no doubt room for improvement. The recursive nature of: f'{o.name:{o.len}}' will complicate some of the optimizations I've been thinking of.
There is (or was) a special case for formatting str, int, and float to bypass the .__format__ lookup. I haven't looked at it since the PEP 393 work.
Looks like it's still there. Also for complex! Eric.