-1
one = 'one'
two = 'two'
three = 'three'

Are the 2 equivalent in time complexity?


result_1 = f'{one}{two}{three}'
result_2 = ''.join([one, two, three])

I know that join works in linear time. But is the same true also for f-strings? With f-strings, the number of strings being concatenated is always a constant, so I guess one could say it's constant time complexity, but I was more curious to know how the concatenation is implemented and how it would fare with a large number of strings.

okokok
  • 11
  • 1
    Most operations you do with a string are linear with respect to the length of the string. – Samwise May 21 '23 at 06:47
  • 1) Yes. 2) The f-string is parsed by the compiler and can be compiled into an optimal in-line concatenation sequence. What actually happens (in both cases) is liable to depend on the Python implementation and version. – Stephen C May 21 '23 at 06:48
  • _"With f-strings, the number of strings being concatenated is always a constant, so I guess one could say it's constant time complexity"_ - If you have a constant number of strings, it is constant regardless of how you concatenate them. In the other hand, the lengths of strings are not constant. For relatively short strings, the time complexity is irrelevant. What you would be interested in, if speed was critical, is the absolute time rather than time complexity. – zvone May 21 '23 at 07:02

1 Answers1

1

The performance of these two approaches may vary between releases of Python and could also depend on your hardware.

In Python 3.11.3 on macOS 13.4 (3 GHz 10-Core Intel Xeon W) the f-string implementation is faster than str.join()

from timeit import timeit

ONE = 'one'
TWO = 'two'
THREE = 'three'

def func1(one, two, three):
    return f'{one}{two}{three}'

def func2(one, two, three):
    return ''.join([one,two,three])

for func in func1, func2:
    print(func.__name__, timeit(lambda: func(ONE, TWO, THREE), number=2_000_000))

Output:

func1 0.2694316829999934
func2 0.33222394099993835

Note:

This result will be due in part to the fact that func2 has to construct a list. This can be eliminated by re-writing it as:

def func2(*args):
    return ''.join(args)

...which timeit reports as:

func2 0.30138257099997645
DarkKnight
  • 19,739
  • 3
  • 6
  • 22