1

So I have been playing around with f-strings and their speeds in comparison in different scenarios. I ran into a scenario where f strings are slower.

Edit: x = 0

In[1]: %timeit f"{x:0128x}"
363 ns ± 1.69 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In[2]: %timeit '%0128x' % x
224 ns ± 1.37 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In[3]: %timeit f"{x:0128X}"
533 ns ± 22 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In[4]: %timeit "%0128X" % x
222 ns ± 0.408 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Why are f-strings slower in this scenario, and why is 'X' so much slower than 'x' for f-strings?

11
  • One sidenote: I'm not sure if title should be "hexifying strings" if the original value x is an integer. Commented Sep 11, 2017 at 18:44
  • Perhaps a better way to state is is "using hexadecimal formatting" Commented Sep 11, 2017 at 18:45
  • You can edit the title. Commented Sep 11, 2017 at 18:45
  • 1
    because one (f-strings) is a much more complex operation than the other. Commented Sep 11, 2017 at 18:48
  • 1
    Note that you should really avoid using different scopes. % x uses x as a local, f"..." may well be looking up x as a global. Put both in a function to ensure equal scopes. I then get 430ns and 304ns per loop. Commented Sep 11, 2017 at 18:50

1 Answer 1

2

String interpolation with %x (and other numeric conversions) can't be overloaded, so the interpreter can perform it quickly.

f-strings are the same thing as the format() built-in function, which needs to look for a __format__ method on the object. This is slower.

For instance, this class can override %s and format(), but can't override %x:

class myint(int):
    def __format__(self, spec):
        return "example"
    def __int__(self):
        return "example"
    def __str__(self):
        return "example"
    def __repr__(self):
        return "example"
>>> '%x' % myint()
'0'

Capitalizing the string, in the CPython implementation, first builds the lowercase string then loops over the string to change the case.

Overriding __str__, even to return a constant string, will also make %s slower than %x, since it involves a method call.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the insight. I think the biggest problem was how these functions were looking for the original x value. Since the test I showed above had x as a prior declaration, it showed the numbers drastically different than setting x as a local variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.