-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Add a private implementation of a String initializer with access to uninitialized storage (https://github.com/apple/swift-evolution/pull/1022) and use it to speed up uppercased() and lowercased() #26007
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
Add a private implementation of a String initializer with access to uninitialized storage (https://github.com/apple/swift-evolution/pull/1022) and use it to speed up uppercased() and lowercased() #26007
Conversation
@swift-ci please test |
@swift-ci please benchmark |
Build failed |
393a1df
to
68eac61
Compare
@swift-ci please test |
@swift-ci please benchmark |
Build failed |
Build failed |
Performance: -O
Code size: -O
Performance: -Osize
Code size: -Osize
Performance: -Onone
Code size: -swiftlibs
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to fix nul-termination, other than that LGTM
1e70d94
to
1c9bfe2
Compare
@swift-ci please test |
@swift-ci please benchmark |
Build failed |
Build failed |
Performance: -O
Code size: -O
Performance: -Osize
Code size: -Osize
Performance: -Onone
Code size: -swiftlibs
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
@swift-ci please test |
Build failed |
You should split the new benchmarks and the code improvements (the optimizations) into separate PRs so that you can measure the latter. Otherwise you are seeing only the “After” state in the Added. It also looks like we have a small workload sizing issues after the excellent improvements (🤓😱👏) on |
/// specified number of UTF-8 code units. | ||
@inline(__always) | ||
internal init( | ||
uninitializedCapacity capacity: Int, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this requires an underscored prefix as per stdlib naming convention, does it not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's intended to be made public; there's a S-E pitch thread.
@inline(__always) | ||
internal init( | ||
uninitializedCapacity capacity: Int, | ||
initializingUTF8With initializer: ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit
initializingUTF8With initializer: ( | |
initializingUTF8With initializer: ( |
The new benchmarks are for when we adopt the new initializer in Foundation later; this PR won't change them at all. |
…ninitialized storage (swiftlang/swift-evolution#1022) and use it to speed up uppercased() and lowercased()
1c9bfe2
to
b06137b
Compare
@swift-ci please test |
Build failed |
Build failed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, trivial suggestions.
if _fastPath(smol.isASCII) { | ||
self = String(_StringGuts(smol)) | ||
} else { | ||
//We succeeded in making a _SmallString, but may need to repair UTF8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after //
) | ||
return result.asString | ||
case .error(let initialRange): | ||
//This could be optimized to use excess tail capacity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after //
let buffer = UnsafeMutableBufferPointer(start: storage.mutableStart, | ||
count: capacity) | ||
let count = try initializer(buffer) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this just end in a call to _updateCountAndFlags
or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_updateCountAndFlags checks invariants, and this particular initializer doesn't guarantee that all logically invariant things (for example "has ascii contents and claims to be ascii") hold, which is why I didn't use it in this one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One day I'll refactor all this logic to flow more reasonably, make the stored properties private, etc., and then have a dedicated bit for "this has passed through some sanctioned create call".
Fixes https://bugs.swift.org/browse/SR-11069