Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String concatenation with + vs. f-string

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.

like image 596
JamesWang Avatar asked Dec 04 '19 16:12

JamesWang


1 Answers

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:

results

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
like image 184
SyntaxVoid supports Monica Avatar answered Oct 02 '22 17:10

SyntaxVoid supports Monica