There comes a time in every software engineer’s life when they come up with a new binary-to-decimal floating-point conversion method. I guess my time has come. I just wrote one, mostly over a weekend: https://github.com/vitaut/zmij.
It incorporates lessons learned from implementing Dragon4, Grisu and Schubfach along with a few new ideas from myself and others. The main guiding principle is Alexandrescu’s “no work is less work than some work” so a number of improvements come from removing things from Schubfach (conditional branches, computations and even candidate numbers).
Performance
Here is how it performs on dtoa-benchmark:
~68% faster than Dragonbox, the previous leader (at least among algorithms with correctness proofs)
~2 times faster than my Schubfach implementation that closely follows the original paper
~3.5 times faster than std::to_chars from libc++ (Ryu?)
from libc++ (Ryu?) ~6.8 times faster than Google’s double-conversion (Grisu3)
~59 times (not percent!) faster than sprintf on macOS (Dragon4?)
Converting a single double takes about 10 to 20 ns on Apple M1.
... continue reading