-
Notifications
You must be signed in to change notification settings - Fork 288
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
Conversion is slow for numbers with no more than 17 non-zero bits after the binary point. #28
Comments
Normally there should only be ~0.5% of all doubles that bail out to slow-mode, and it shouldn't be because of a 2^17 division. With respect to mode 4: I would like to avoid adding more API surface to the library, but if you are just interested in fast conversions (not necessarily caring for optimal results) I could send you pointers to different implementations. In particular, there exists an implementation that never falls back to bignum-mode, but isn't necessarily optimal (that is, could give you longer than necessary numbers). Here are the sources: http://florian.loitsch.com/publications/bench.tar.gz Grisu just prints 17 digits as fast as possible and is generally the fastest you can get. |
Thanks for the links. I need correct conversions but I want them fast, so I may end up patching double-conversion to provide something like dtoa's mode 4. I may look at speeding up BignumDtoa too, perhaps by using 64-bit limbs on 64-bit hosts. |
Apparently I misunderstood your explanation of dtoa's mode 4. I thought it would at most emit 10 digits (which would obviously lead to bad output for the numbers that need more than 10). Grisu and Grisu2 both produce correct numbers. They are just sometimes not the shortest. From my understanding, that's pretty close to mode 4. If you don't care for the length of the output, Grisu is the fastest. If you prefer nicer output (but can live with longer ones) Grisu2 is the next best choice. I still need to find some time to look into the perf-issues for x/2^17 numbers. |
You didn't misunderstand. That's correct. When I said I need correct conversions, I meant that I need to get results that are identical to the results I used to get from dtoa's mode 4. Currently I am achieving this by calling DoubleToAscii but massaging the result if it's longer than 10 digits. |
I started to look at this issue. The problem is, that
It's important to see that the last
Removing that 'if' will still produce valid output, but doesn't care if it choses the closest if several decimal numbers read back to the same double. Note that Grisu2 would not have any problems with the number: it would just pick one of the two since it doesn't stop if the output is not optimal (but still correct). I still need to figure out, if there is a good way to avoid the bailout. |
I've noticed a fairly large class of numbers for which double-conversion is slow to produce the shortest decimal representation. Here's a test case:
On my machine (Ubuntu 15.10, Haswell CPU) I get:
So for random integers divided by 2^17 it's running 6x slower than for some other random inputs. Profiling shows that this is because FastDtoa() is usually (always?) failing, so it has to fall back to BignumDtoa(). Is this expected? Is there a way to make FastDtoa() cope with more cases?
Incidentally, I noticed this when benchmarking our software (which now uses double-conversion) against a previous version that used David Gay's dtoa(), using his mode 4 to get the shortest representation but limited to 10 digits. double-conversion doesn't seem to have an equivalent of mode 4, so we're forced to use SHORTEST mode, which makes double-conversion appear slower than dtoa() on random integers / 2^17.
The text was updated successfully, but these errors were encountered: