Hi all,
Admittedly, the Foundation.Decimal type is the product of another time. It doesn't represent infinity or negative zero, for example, characteristics that are decidedly unlike those of standard IEEE types and that preclude conformance to the standard library's FloatingPoint protocol. We probably wouldn't design a decimal floating-point type from scratch today in a similar way. Still, this is the decimal floating-point type that Swift has today (now cross-platform!), and it continues to see active use. I'm excited to share some recent work that's shown how much better Foundation.Decimal can be on its own terms.
To set the table, @hassila announced this past spring that Ordo One contributed a fix to swift-foundation removing heap allocations for a 3–5× improvement in performance—hugely inspiring. Still, the type was a long ways away from performing in the same ballpark as fixed-point decimal types. Was the gap entirely because floating-point math is just that much more costly, or could we close the gap still further?
As it turns out, even without dynamic allocations, the swift-foundation implementation for Decimal performed many operations one 16-bit limb at a time. By using 128-bit integer primitives instead and some other not-too-fancy optimizations, two successive PRs (1, 2) combine with the existing Ordo One contribution to improve performance by a cumulative 15–40× in benchmarks from the prior baseline (when shipped in a future toolchain—not in 6.4). What's more, a number of issues with correct rounding and loss of precision have been addressed: arithmetic that previously ignored the requested rounding mode now honors it, and NSDecimal* APIs now more consistently report loss of precision for inexact results. (And the two PRs do this with close to zero net change in production lines of code.)
With users now able to depend on certain API guarantees that were previously vacuous, these implementation-level changes actually bring to the foreground some API-level tweaks which I think probably ought to roll out in tandem. For that reason, I'll be assembling an initial bundle of (probably rather niche) changes to pitch shortly. Hopefully, interested parties will come forward and chime in on whether that pitch hits the right notes.
For the moment, though, I hope folks using the Foundation.Decimal type will find these improvements to be as delightful to use as I found them to implement!
Xiaodi