Recently, upon spotting a use of Regex
in the wild to achieve the equivalent of a literal string replacement, I wondered about the performance implications of using Regex
this way. To my surprise, I learned that using String.replacing(Regex...)
is actually about 50% faster than using String.replacing(String...)
. In my tests, I ran thousands of iterations for each scenario, including the use of Emoji characters, multiple replacements, etc, and in every test I made, a call like this:
myString.replacing(/foo/, with: "bar")
Is about 50% faster than:
myString.replacing("foo", with: "bar")
This made me wonder if Regex might have received more performance attention than the code path that .replacing(String)
passes through, and if so, maybe it would make sense for the implementation of the latter to simply call through to the former?
After observing the difference in performance between the two above, I wondered how NSString would fare, so I changed the Swift String version to:
(myString as NSString).replacingOccurrences(of: "foo", with: "bar")
To my astonishment, this version is around 50x faster than the Swift Regex case. Here is a typical Instruments Time Profiler run with each of the Regex, Swift String, and NSString cases running in succession:
I know there are sophisticated Unicode correctness issues at play in Swift String, and the C-based counterpart might be benefiting from speed of incorrectness. But these disparities, both the one that causes Regex to perform better than a literal string, and the one where NSString soundly wallops Swift String, made me wonder if there is room for improvements here.
I'd love to hear from anybody with experience in this area of the code base about whether they think there is merit in filing a bug or otherwise pursuing improvements here.
Daniel