Fast function to parse strings into double (binary64) floating-point values
github.com
github.com
edit: also, ~2.5KB of that is due to padding in power_of_ten_components. I wonder if it'd be better to split the uint64_t field into two uint32_ts to avoid this.
[1] https://github.com/lemire/fast_double_parser/blob/master/inc... [2] https://news.ycombinator.com/item?id=22440894 [3] https://en.wikichip.org/wiki/amd/ryzen_embedded/r1606g
And like anything, it depends on what you're doing. If you're doing lots of server-to-server RPCs on big distributed systems like within Google, it's much more reasonable to start with protobuf or the like than with JSON. And not just for performance reasons; having the generated code helps a lot with maintainability. (Some JSON libraries have something similar; some don't.)
* have a shorter exponent and/or mantissa to make each number shorter and the overall series more repetitive. (maybe even skip the mantissa if you only care about order of magnitude! call it the opposite of fixed-point, or just storing the logarithm of the value, whatever terminology works for you...)
* skip the sign bit for a non-negative series (e.g., deltas of a non-decreasing series),
* use a variable-width bitstream encoding like exp-Golomb to represent the exponent and/or mantissa,
* use run-length encoding if it's repetitive (after delta-encoding),
* etc.
One byte per value (or less!) is surely possible in some cases. But I've never done it myself and agree fixed-point sounds much more pleasant. One of my projects represents deltas of durations in units of 90,000ths of a second, varint-encoded. I much prefer that to dealing with float seconds.
Err, surely it should be equal to 10,000,000,000. Or more probably, they meant to write "1.0e1".
But the reality is the core of the algorithm is still a while loop that looks at each digit one at a time and multiplies by 10 each time ...
Very cool btw
Source: I regularly optimise C++ code in LibreOffice.
It looks like Rust is doing well on this. HashMap (the one everybody uses) is essentially a clone of Google's heavily-optimized C++ hash table:
https://abseil.io/blog/20180927-swisstables
... and if you need the collection to be sorted, their BTreeMap has much lower overhead than the C++ std::map, plus a big prominent note in its documentation saying that HashMap is usually the one you want.
I'm impressed. (Haven't looked at Zig yet.)
It didn't start out this way, but their spec was not so constrained as C++, so they were able to switch to this implementation in a backward-compatible way. In particular, Rust's std::collections::HashMap doesn't guarantee that keys and values have stable addresses across mutations of unrelated entries, so they can use open addressing rather than chaining. (And they did use open addressing from the beginning; the SwissTables-like "hashbrown" implementation was just a refinement of that.)
I think a lot of this is just that newer languages can learn from the mistakes of previous languages. It will be interesting to see how Rust (and other newer languages) are able to evolve when their standard library is 20+ years old and some parts don't age so well. (Although actually C++'s std::unordered_map only goes back to C++11 and still sucks...)
One part of Rust's answer I think is to keep the standard library small. Less there, less to screw up. Make it easy to pull in crates instead. Crates can supply the same functionality but can bump their major version relatively easily if the interface has to change. There are advantages and disadvantages to this approach...
Is there an equivalent data structure that has better worst-case time complexity than red-black tree?
Same big-O, but faster by a big linear multiplier.
[0]: http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performa...
That said, I've never seen strtod showing up in my profiles, but I bet if I was profiling web browsers then I would see it.
Jeroen van der Zijp, developer of the lesser known FOX Toolkit, claims to have done better than the Ryu algorithm. From his changelist [0]:
> New, faster, and often more accurate floating point to string conversion. No, this is not based on Ryu paper. New method reliably generates 16 digits, and does much better rounding.
I believe this [1] is his implementation in C++. See also his paper [2]. (I believe it's not peer-reviewed, but it does appear in Google Scholar.)
[0] http://www.fox-toolkit.org/
[1] https://github.com/gogglesguy/fox/blob/77396c638c1c4e05/lib/...
[2] http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf