The problem/use-case that the feature addresses

Putting it simply all use cases that heavily rely on string to floating-point conversion, (e.g. meaning take a string like "1.5" and return a 64-bit double-precision floating-point number like 1.5 ), could benefit from a performance boost by swapping strtod by the equivalent fast_double_parser, as measured by Daniel Lemire ( @lemire on GH ) on his blog https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/ :

parser MB/s
fast_double_parser (new) 660 MB/s
abseil, from_chars 330 MB/s
double_conversion 250 MB/s
strtod 70 MB/s

The 99% cases performance improvement and correctness of 100%: Putting it simply, when we cannot use the Eisel-Lemire algorithm we fall back to the equivalent strtod, meaning this change is 100% compatible.

Real application use-case

We've applied the fast_double_parser to a Redis Module ( RedisTimeSeries ) by leveraging a C Wrapper for the C++ Eisel-Lemire ParseFloat algorithm, and noticed a bump in performance on our write workflows of ~=8% on the achievable ops/sec, as detailed here: https://github.com/RedisTimeSeries/RedisTimeSeries/pull/683. For the redis use-case I believe we should not use C++ at all and rely upon solely on a C header-only library ( as described bellow ).

Description of the feature

Leverage a C Header only library ( based on the C++ one available here: https://github.com/lemire/fast_double_parser/blob/master/include/fast_double_parser.h )

Additional information

I would very much like to push this POC forward, meaning I volunteer to make available and test the C header-only lib and apply it to Redis and check the performance improvements :)

Comment From: lemire

The approach in question has now been adopted in Go (standard library), Rust (standard library) and LLVM (standard library). There is also a new C++ library at https://github.com/fastfloat/fast_float which is more generic.

Comment From: lemire

The fast float library is now part of WebKit (Safari).

Comment From: filipecosta90

@lemire I'll prepare a quick POC and check the impact on Redis :)

Comment From: filipecosta90

@lemire would it be possible for you to review if #11884 is the best way of including fast_float on redis with the minimum possible changes to the redis codebase? I'm literally just using your amalgamate script and wrapping it via:

/* Convert NPTR to a double using the fast_float library.
 * If ENDPTR is not NULL, a pointer to the character after the last one used
 * in the number is put in *ENDPTR.  */
extern "C" double fast_float_strtod(const char *nptr, char **endptr) {
  double result;
  auto answer = fast_float::from_chars(nptr, nptr + strlen(nptr), result);
  if (endptr != NULL) {
    *endptr = (char *)answer.ptr;
  }
  return result;
}

PS: also check https://github.com/fastfloat/fast_float/pull/183

Comment From: lemire

@filipecosta90 As I wrote in the PR, your code is fine except that it is not ideal for error handling... we follow the from_chars approach from C++17 which goes as follows...

  const std::string input =   "234532.3426362,7869234.9823,324562.645";
  double result;
  auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
  if(answer.ec != std::errc()) {
    // check error
  }
  // we have result == 234532.3426362.
  if(answer.ptr[0] != ',') {
    // unexpected delimiter
  }
  answer = fast_float::from_chars(answer.ptr + 1, input.data()+input.size(), result);
  if(answer.ec != std::errc()) {
    // check error
  }
  // we have result == 7869234.9823.
  // answer.ptr will point at the first ','

Comment From: lemire

The latest version of the library can also parse integers (including hex.). It is part of GCC as of GCC 12. We also added SIMD optimizations for better speed (with support for ARM and x64).

https://github.com/fastfloat/fast_float/releases/tag/v6.0.0