-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Reimplement Floating-Point Parsing in pure Swift #85797
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
base: main
Are you sure you want to change the base?
Conversation
|
@swift-ci Please test |
|
|
||
| #if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64)) | ||
|
|
||
| @available(SwiftStdlib 5.3, *) |
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.
@stephentyrone Any thoughts on whether I can delete this entire function? Since it was public before, it's conceivable that someone was calling it directly, but no stdlib code ever called it.
|
@swift-ci Please test |
|
@swift-ci Please test |
3 similar comments
|
@swift-ci Please test |
|
@swift-ci Please test |
|
@swift-ci Please test |
| // Caveat: _swift_stdlib_strto{f,d,ld}_clocale() was called directly from inlineable | ||
| // code until Feb 2020 (commit 4d0e2adbef4d changed this), so they need to be | ||
| // exported with the same C-callable ABI for as long as we support code compiled | ||
| // with Swift 5.3. |
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.
Do we have a test calling the compatibility symbols directly, to avoid inattention-induced rot?
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.
We have the ABI checks to verify the symbols are still present, but you're right that it would be good to have something stronger.
|
@swift-ci Please test macOS |
This reimplements the underlying support for `Float16(_:StringSlice)`, `Float32(_:StringSlice)`, and `Float64(_:StringSlice)` in pure Swift, using the same core algorithm currently used by Apple's libc. Those `StringSlice` initializers are in turn used by `Float16(_:String)`, `Float32(_:String)`, and `Float64(_:String)`. **Supports Embedded**: This fully supports Embedded Swift and insulates us from variations in libc implementations. **Corrects bugs in Float16 parsing**: The previous version of `Float16` parsing called libc `strtof()` to parse to a 32-bit float, then rounded to `Float16`. (This was necessary because float16 parsing functions are not widely supported in C implementations.) This double-rounding systematically corrupted NaN payloads and resulted in 1 ULP errors for certain decimal and hexadecimal inputs. The new version parses `Float16` directly, avoiding these errors. **Modest perforamnce improvement**: The old version had to copy the Swift string to construct a C string. For inputs longer than 15 characters, this typically required a heap allocation, which added up to 20% to the runtime. The new version parses directly from a Swift string, avoiding this copy and heap allocation.
Because these support functions used to be implemented in C, they could be present on macOS x86_64, even though Float16 isn't supported there otherwise. With the new Swift implementation, we can't define these functions on x86_64 macOS, so remove them from the expected list.
06ce320 to
69857f4
Compare
This reimplements the underlying support for
Float16(_:Substring),Float32(_:Substring), andFloat64(_:Substring)in pure Swift, using the same fast algorithms currently used by Apple's libc. ThoseSubstringinitializers are in turn used byFloat16(_:String),Float32(_:String), andFloat64(_:String).Supports Embedded: This fully supports both Embedded and non-Embedded Swift and insulates us from variations in libc implementations.
Corrects bugs in Float16 parsing: The previous version of
Float16parsing called libcstrtof()to parse to a 32-bit float, then rounded toFloat16. (This was necessary because float16 parsing functions are not widely supported in C implementations.) This double-rounding systematically corrupted NaN payloads and resulted in 1 ULP errors for certain decimal and hexadecimal inputs. The new version parsesFloat16directly, avoiding these errors.Modest performance improvement: The old version had to copy the Swift string to construct a C string. This often incurred a heap allocation, which added up to 20% to the runtime. The new version parses directly from a Swift string, avoiding this copy and heap allocation.