google / google/double-conversion
StringToDoubleConverter::StringToDouble slower than dtoa
- 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
Assessment
This issue has not been assessed yet.