Friday, March 9, 2018

Faster Swift String Concatenation

Nick Lockwood:

I’m sure I heard somewhere that "\(foo)\(bar)" is the recommended way to do string concatenation in Swift, but I benchmarked it and it’s almost 100x slower than using + or String.append().

I know I’ve heard that as well. I assumed it was taken as a hint to figure out the proper allocation size up front. But currently it’s slower because the interpolated elements are not assumed to be strings.

Joe Groff:

Yeah, \(x) goes through the print-anything path for x, which hasn’t really been optimized

Steve Barnegren:

I thought that the recommendation to use "\(foo)\(bar)" over + was more for compilation performance than runtime performance, as the compiler has to work to understand which + operator to use.

Joey Devilla:

Running on the phone, the + method is almost 70 times faster, which is a significant difference when concatenating a large number — 100 million — strings. If you’re concatenating far fewer strings, your better bet is to go with the option that gives you the more readable, editable code.

Marcel Weiher:

A factor 100 here, a factor 100 there, soon enough… ¯\_(ツ)_/¯

Nick Lockwood:

A lot of people have jumped on this to criticise Swift’s maturity as a language.

To put it in context, even at 100x slower, you can still comfortably perform 500,000 string concatenations per second. In most apps this would be a complete non-issue.

Update (2018-03-10): Nick Lockwood:

Deleted this, since it was due to a misconception on my part.

His original test measured foo = "\(foo)bar" vs. foo += "bar", which is not what I would have expected from the tweet’s description. The latter is 100x faster because Swift is able to mutate the string rather than create a new one. The benchmark code is here.

I measured baz = "\(foo)\(bar)" vs. baz = foo + bar, which is what I thought he was originally talking about (i.e not building up a giant string), and found the latter to be about twice as fast, perhaps because of the overhead that Groff mentioned.

Devilla measured newString = "\(string1) \(string2)" vs. newString = string1 + " " + string2 and found the latter to be 70x faster. I tried to reproduce this but found less than 10% difference in the opposite direction. In other words, interpolation was slightly faster. However, I am using Swift 4, and he was using Swift 2.

1 Comment RSS · Twitter

Leave a Comment