Feature #21308
openReplacing the Float#to_s (dtoa.c) implementation with a modern algorithm
Description
This is a feature request to replace Ruby's Float#to_s implementation with a modern high-performance float-to-string conversion algorithm such as Grisu.
Currently, Float#to_s in Ruby uses the BSD-derived implementation in missing/dtoa.c.
Meanwhile, json gem has adopted a Grisu-based implementation in ruby/json#768, it has been improve the performance of float-to-string conversion dramatically.
It appears to have brought about a 10 times improvement in performance.
However, the improvement is limited to the json gem.
If we can use the same implementation in Float#to_s, it will introduce the improvement in all float-to-string conversion cases.
(In additional, it would be better if an API could be added that could be called directly from the C extension library, it will reduce the overhead of the call.)
Updated by nobu (Nobuyoshi Nakada) over 1 year ago
The interface of fpconv_dtoa() looks quite different from dtoa() in missing/dtoa.c.
Rather grisu2() itself is closer?
Updated by radiospiel (Enrico Thierbach) over 1 year ago
The change in https://github.com/ruby/json/pull/768 was an easy win, because the previous implementation was calling into questionFloat#to_s via rb_funcall. The overhead of doing so is so extreme, that any implementation that would skirt that would show a massive improvement already.
In fact, a first attempt using dtoa.c already showed a 600% or so performance improvement on a clinical example.
I then decided that maybe this would also be a great moment to look at alternative implementations, since the flexibility provided by dtoa.c is not necessary in the context of the json gem. Other motivational factors have been:
- dtoa generates output right to left (IIRC), but, at least for an integration with the json gem, generating left to right saves a memcpy, which would add a 5-10% overhead;
- more modern algorithms are readily available.
I believe integrating a more modern implementation in the ruby runtime certainly is benefitial, but the gains are not as massive as @watson1978 (Shizuo Fujita) hopes to achieve here, unfortunately.
Updated by watson1978 (Shizuo Fujita) 13 days ago
Looks like we are about to get yet another vendored implementation of the same kind: https://github.com/ohler55/oj/pull/1095 proposes vendoring the same Boost-licensed fpconv (Grisu2) code that the json gem already ships.
I think it is time to address this in Ruby itself rather than gem by gem.