-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-7136] Fast-path ad-hoc printing of Strings #49684
Comments
Starter bug potential implementation: Look for |
Comment by Yuki Kuroda (JIRA) I tried this issue with this PR. |
@jckarter darquro (JIRA User) do you have code observing this slowdown? Can we add it to our regression benchmarks? |
@nicklockwood observed on Twitter that string interpolation was 100x slower than append()-ing: https://twitter.com/nicklockwood/status/971506873387143168 Maybe he can share his microbenchmark? |
Sorry everyone, it turns out I'm an idiot. I was comparing foo = "(foo)bar" against foo += "bar" and not foo = foo + "bar" which of course is not a fair comparison since the former is updating in place, and the latter is copying the buffer each time. I re-ran the benchmark and found that interpolation is almost identical to using +. I did, however discover that foo.appending(bar) is significantly slower than foo + bar, so maybe there's something worth investigating there? Benchmark: https://gist.github.com/nicklockwood/9a5b846f9535c1f1e5743429a9ccd71f |
Thanks for following up @nicklockwood! I wonder whether the difference in `+` and `appending` comes down to the difference in their calling conventions, since as currently implemented Swift will pass regular function arguments at +1 and 'self' at +0. Both operations would be strong candidates for passing at +1 when we add keywords for controlling the calling convention, since it would be useful for both functions to do an in-place append when one of the arguments is passed in the unique reference to a buffer. |
How does +1 improve things here? For Array, you have the chance to become the last use of a non-trivial single-element append. But with String, you're always copying the underlying code units, which are trivial. |
I suppose it has the most benefit for only the left hand side of the append, since you can do a |
Also, the standard library doesn't implement `appending` for String. You're getting the one from https://github.com/apple/swift/blob/master/stdlib/public/SDK/Foundation/NSStringAPI.swift#L1011, where the Foundation overlay implements something with a bunch of potential bridging and copying back and forth. These should really be reconciled into some kind of consistent story, ala https://forums.swift.org/t/rfd-reconciling-nsstring-and-string/10350 CC Lance (JIRA User) edit: grammar and CC |
The simple appending case for String could be improved just by providing specific extension... Although the example below is probably not the best way to do it. extension String { public func appending(_ aString: String) -> String {
} } |
Attachment: Download
Additional Detail from JIRA
md5: 2686733126be82154b524085fb9de797
Issue Description:
Using Strings with print, string interpolation, String(describing:), etc., is extremely common, but goes through the generic protocol testing dispatch mechanism everything does. We should dynamically check whether something is a String and just print the string.
The text was updated successfully, but these errors were encountered: