Skip to content

Conversion is slow for numbers with no more than 17 non-zero bits after the binary point. #28

@jayfoad

Description

@jayfoad

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:

#include "double-conversion.h"
using namespace double_conversion;

int main()
{
    size_t i = 0;
    for (int j = 0; j < 5e6; j++)
    {
#ifdef FAST
        double d = (rand() % 1000000) / 100000.0; // 10^5
#else
        double d = (rand() % 1000000) / 131072.0; // 2^17
#endif
        char buf[20];
        bool s;
        int length, decpt;
        DoubleToStringConverter::DoubleToAscii(d, DoubleToStringConverter::SHORTEST, 0, buf, sizeof buf, &s, &length, &decpt);
        i += strlen(buf);
    }
    return i % 1000;
}

On my machine (Ubuntu 15.10, Haswell CPU) I get:

$ g++ -O3 *.cc -o foo -DFAST && time ./foo
real    0m0.446s
user    0m0.444s
sys 0m0.000s
$ g++ -O3 *.cc -o foo && time ./foo
real    0m2.402s
user    0m2.400s
sys 0m0.000s

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions