google / google/double-conversion

StringToDoubleConverter::StringToDouble slower than dtoa

Open
#153 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.2k
Forks
308
Avg merge
2d 9h
Merged PRs (30d)
12

Description

I'm trying to switch the string-to-double code in SpiderMonkey from dtoa.c to `StringToDoubleConverter`. This code is used by the JS parser, JSON parser and `parseFloat`, so is somewhat perf sensitive. The code I'm using (slightly simplified to show only the 1-byte-chars code):
```cpp
using SToDConverter = double_conversion::StringToDoubleConverter;
SToDConverter converter(SToDConverter::ALLOW_TRAILING_JUNK, emptyStringValue,
/* junk_string_value = */ JS::GenericNaN(),
"Infinity", "NaN");
int processed = 0;
double d = converter.StringToDouble(reinterpret_cast(s), length, &processed);
```
This works and passes all tests, but is quite a bit slower than dtoa.c when the string contains more than a few digits. Some micro-benchmark results:

| code (10 million times) | dtoa | double-conversion |
| ---- | ---- | ----|
| `parseFloat("1.1")` | 318 ms | 402 ms |
| `parseFloat("3.14")` | 335 ms | 423 ms |
| `parseFloat("12345.678")` | 385 ms | 513 ms |
| `parseFloat((i % 1024) + ".5")` | 617 ms | 725 ms |

A big part of this is that `StringToIeee` supports a number of flags and this adds overhead: if I add a `const int flags_ = ALLOW_TRAILING_JUNK` to the start of that function, as a hack to let the C++ compiler eliminate branches, I get better times (346, 370, 453, 665 ms for the ones above). Still not quite as fast as dtoa, but it closes half of the gap. The JSC folks [ran into this too](https://github.com/WebKit/WebKit/commit/b92c3dc201dac3a1bd3ae40eb996ab11d1a61c94), they changed the code to eliminate those branches (and used a static method instead of the converter instance).

Is there anything that could be done to provide a faster implementation for this use case?

I also don't know yet where the rest of the slowdown is from. I know dtoa.c is horrible code so maybe this was an intentional trade-off to reduce complexity?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.