Let's say I have two variables:
>>> a = "hello"
>>> b = "world"
I can concatenate them in two ways; using +
:
>>> a + b
"helloworld"
Or using an f-string:
>>> f"{a}{b}"
"helloworld"
Which way is better or a better practice? Someone told me the f-string is better practice in terms of performance and robustness, and I'd like to know why in detail.
Performance wise, I would have expected the format string literal to be significantly faster than string concatenation however I was shocked to find this was not the case.
I used the timeit
module to test how long it took format string literals vs. string concatenation. I tested strings of length 10 to 1 million characters.
from timeit import timeit
import matplotlib.pyplot as plt
n = 1000000000
setup = """\
a = 'a'*{str_len}
b = 'b'*{str_len}
"""
fstr_stmt = """\
f'{a}{b}'
"""
concat_stmt = """\
a+b
"""
str_lens = [10, 100, 1000, 10000, 100000, 1000000]
fstr_t = []
concat_t = []
for str_len in str_lens:
n_iters = n//str_len
fstr_t.append(timeit(setup=setup.format(str_len=str_len), stmt=fstr_stmt, number=n_iters)/n_iters)
concat_t.append(timeit(setup=setup.format(str_len=str_len), stmt=concat_stmt, number=n_iters)/n_iters)
ratio = fstr_t[-1]/concat_t[-1]
print(f"For two strings of length {str_len:7d}, concatenation is {ratio:.5f} times faster than f-strings")
plt.plot(str_lens, fstr_t, "r*-")
plt.plot(str_lens, concat_t, "c*-")
plt.xscale("log")
plt.yscale("log")
plt.xlabel("String length (log scale)")
plt.ylabel("Seconds per iteration (log scale)")
plt.grid()
plt.show()
Console Output:
For two strings of length 10, concatenation is 1.06938 times faster than f-strings
For two strings of length 100, concatenation is 1.14887 times faster than f-strings
For two strings of length 1000, concatenation is 1.13994 times faster than f-strings
For two strings of length 10000, concatenation is 1.26934 times faster than f-strings
For two strings of length 100000, concatenation is 1.21585 times faster than f-strings
For two strings of length 1000000, concatenation is 1.01816 times faster than f-strings
And the plot:
Summary: Using the string concatenation operator is slightly faster than using format string literals. Unless you are performing many hundreds of thousands of string concatenations and need them done very quickly, the implementation chosen is unlikely to make a difference.
From a readability standpoint, f-string literals are more aesthetically pleasing and easier to read than string concatenation. Also, as the answer from Daniel points out, f-strings are able to handle inputs of different types while using +
requires both objects to be strings (or the overloading of the __add__
, and __radd__
methods).
Edit: As chepner points out in their comment, using f-strings is more efficient when more than two strings are involved. For example, adding another variable, c
, to the setup and timeit
statements yields the following console output:
For three strings of length 10, concatenation is 0.77931 times faster than f-strings
For three strings of length 100, concatenation is 0.67699 times faster than f-strings
For three strings of length 1000, concatenation is 0.60220 times faster than f-strings
For three strings of length 10000, concatenation is 1.27484 times faster than f-strings
For three strings of length 100000, concatenation is 0.98911 times faster than f-strings
For three strings of length 1000000, concatenation is 0.60201 times faster than f-strings
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With