6

I was wondering what is the fastest way in python to create an empty string to attach more strings to it later on. However, I found that interestingly it's way faster to init a string via "" than str(). Can someone shine a light on this? I guess str() is just coming with a lot of overhead like typecheck etc.

Here is what I tried:

%timeit ""+"a"
7.63 ns ± 0.0376 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit str()+"a"
58.2 ns ± 0.253 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
codeforester
  • 39,467
  • 16
  • 112
  • 140
PlagTag
  • 6,107
  • 6
  • 36
  • 48
  • 8
    `str` has to be called; `""` cannot be overriden and so can be replaced at compile time. – chepner Sep 09 '20 at 18:53
  • You can always compare the bytecode that they both compile to -- the `dis` module is your friend. – Charles Duffy Sep 09 '20 at 18:54
  • 2
    Closely related: [When does python compile the constant string letters, to combine the constant strings to one constant string?](https://stackoverflow.com/questions/14493236/when-does-python-compile-the-constant-string-letters-to-combine-the-constant-st) – Charles Duffy Sep 09 '20 at 18:56
  • You’d have to be doing an awful lot of these for 51ns to become significant in slowing down your code, wouldn’t you? – DisappointedByUnaccountableMod Sep 09 '20 at 18:56
  • 1
    because `str()` involves a function call, and the compiler just folds `"" + "a"` into `"a"` anyway – juanpa.arrivillaga Sep 09 '20 at 18:59
  • 1
    Note, if you care about *performance*, "I was wondering what is the fastes way in python to create an empty string to later on attach more strings to it. " generally, *that isn't the way to create strings performantly*. I.e. don't concatenate strings in a loop, use a list, then `.join` them – juanpa.arrivillaga Sep 09 '20 at 19:00

1 Answers1

11

Because calling a function requires looking up that function and calling it. "" + "a" can just be interpreted as "a". Using dis:

>>> import dis
>>> dis.dis("str() + 'a'")
  1           0 LOAD_NAME                0 (str)
              2 CALL_FUNCTION            0
              4 LOAD_CONST               0 ('a')
              6 BINARY_ADD
              8 RETURN_VALUE
>>> dis.dis("'' + 'a'")
  1           0 LOAD_CONST               0 ('a')
              2 RETURN_VALUE
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103