Skip to content

Using fast_float library for faster parsing of 64 decimal strings.#11884

Merged
sundb merged 11 commits into
redis:unstablefrom
filipecosta90:fast_float
Sep 15, 2024
Merged

Using fast_float library for faster parsing of 64 decimal strings.#11884
sundb merged 11 commits into
redis:unstablefrom
filipecosta90:fast_float

Conversation

@filipecosta90

@filipecosta90 filipecosta90 commented Mar 6, 2023

Copy link
Copy Markdown
Contributor

Fixes #8825

We're using the fast_float library1 in our (compiled-in) floating-point fast_float_strtod implementation for faster and more portable parsing of 64 decimal strings.

The single file fast_float.h is an amalgamation of the entire library, which can be (re)generated with the amalgamate.py script (from the fast_float repository) via the command:

python3 ./script/amalgamate.py --license=MIT > $REDIS_SRC/deps/fast_float/fast_float.h

The used commit from fast_float library was the one from https://github.com/fastfloat/fast_float/releases/tag/v3.10.1

Still TODO:

@lemire

lemire commented Mar 7, 2023

Copy link
Copy Markdown

Upgrading to 3.10.1 might be better: https://github.com/fastfloat/fast_float/releases/tag/v3.10.1

Comment thread deps/fast_float/fast_float_strtod.cpp Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to catch potential errors, you ought to add..

 if(answer.ec != std::errc()) { /* do something */ }

(Note that the library follows the C++ standard so that's how we handle errors. We did not design this approach.)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lemire I've added a error reporting via errno same like strtod.

@lemire

lemire commented Mar 7, 2023

Copy link
Copy Markdown

This looks simple enough. My main concern is that you do not check for the error field after parsing. If you only rarely invoke strtod, then switching to the canonical fast_float API might be simpler. Whether this matters for your application, I do not know.

Note that fast_float relies on the C++17 standard API, so adopting the fast_float API is not akin to vendor lockin... it is a standard!!!

@filipecosta90 filipecosta90 added action:run-benchmark Triggers the benchmark suite for this Pull Request and removed action:run-benchmark Triggers the benchmark suite for this Pull Request labels Mar 13, 2023
@lemire

lemire commented Aug 22, 2023

Copy link
Copy Markdown

Note that the fast_float library has been adopted by webkit (Apple Safari) and other important systems such as GCC.

@CLAassistant

CLAassistant commented Mar 24, 2024

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@fcostaoliveira fcostaoliveira added action:run-benchmark Triggers the benchmark suite for this Pull Request and removed action:run-benchmark Triggers the benchmark suite for this Pull Request labels Aug 18, 2024
@lemire

lemire commented Aug 18, 2024

Copy link
Copy Markdown

The library is now part of Chromium (Chrome etc.).

@fcostaoliveira

Copy link
Copy Markdown
Collaborator

The library is now part of Chromium (Chrome etc.).

Thank you @lemire! I've updated to v6.1.4 using:

git clone https://github.com/fastfloat/fast_float
cd fast_float
git checkout v6.1.4
python3 ./script/amalgamate.py --license=MIT \
  > $REDIS_SRC/deps/fast_float/fast_float.h

will check the results on 2 tests in which we retrive 100 and 1000 elements with float scores and update this PR with results

@fcostaoliveira

fcostaoliveira commented Aug 19, 2024

Copy link
Copy Markdown
Collaborator

Automated performance analysis summary

This comment was automatically generated given there is performance data available.

Using platform named: intel64-ubuntu22.04-redis-icx1 to do the comparison.

In summary:

  • Detected a total of 1 stable tests between versions.
  • Detected a total of 2 improvements above the improvement water line.

You can check a comparison in detail via the grafana link

Comparison between unstable and fast_float.

Time Period from 5 months ago. (environment used: oss-standalone)

Improvements Table

Test Case Baseline unstable (median obs. +- std.dev) Comparison fast_float (median obs. +- std.dev) % change (higher-better) Note
memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score 92577 +- 0.8% (6 datapoints) 108545 17.2% IMPROVEMENT
memtier_benchmark-1key-zset-100-elements-zrange-all-elements 19161 +- 0.7% (7 datapoints) 23062 20.4% IMPROVEMENT

Improvements test regexp names: memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score|memtier_benchmark-1key-zset-100-elements-zrange-all-elements

Full Results table:
Test Case Baseline unstable (median obs. +- std.dev) Comparison fast_float (median obs. +- std.dev) % change (higher-better) Note
memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score 92577 +- 0.8% (6 datapoints) 108545 17.2% IMPROVEMENT
memtier_benchmark-1key-zset-100-elements-zrange-all-elements 19161 +- 0.7% (7 datapoints) 23062 20.4% IMPROVEMENT
memtier_benchmark-1key-zset-1K-elements-zrange-all-elements 3690 +- 0.2% (7 datapoints) 3659 -0.8% No Change

@sundb

sundb commented Aug 19, 2024

Copy link
Copy Markdown
Collaborator

https://github.com/sundb/redis/actions/runs/10450491468
some jobs build failed.

@fcostaoliveira

Copy link
Copy Markdown
Collaborator

https://github.com/sundb/redis/actions/runs/10450491468 some jobs build failed.

@sundb I believe they will all be related to g++ usage. Need to confirm with you guys that g++ dependency is something we're ok with. In the meantime will fix the failures :) thank you!

g++: No such file or directory

@fcostaoliveira

Copy link
Copy Markdown
Collaborator

https://github.com/sundb/redis/actions/runs/10450491468 some jobs build failed.

@sundb can you trigger it again. I believe it's all fixed now

@fcostaoliveira fcostaoliveira requested a review from sundb August 20, 2024 00:34
@sundb

sundb commented Aug 20, 2024

Copy link
Copy Markdown
Collaborator

@fcostaoliveira it failed on 32bit and freebsd: https://github.com/sundb/redis/actions/runs/10463748594

@fcostaoliveira

Copy link
Copy Markdown
Collaborator

@fcostaoliveira it failed on 32bit and freebsd: https://github.com/sundb/redis/actions/runs/10463748594

@sundb now fixed :)
https://github.com/filipecosta90/redis/actions/runs/10499383156/job/29086052819

@fcostaoliveira fcostaoliveira requested a review from lemire August 22, 2024 00:16
@fcostaoliveira fcostaoliveira added the action:run-benchmark Triggers the benchmark suite for this Pull Request label Aug 22, 2024
@fcostaoliveira fcostaoliveira removed the action:run-benchmark Triggers the benchmark suite for this Pull Request label Sep 12, 2024
Comment thread src/object.c Outdated
Comment on lines +790 to +793
value = fast_float_strtod(o->ptr, &eptr);
/* check end pointer is not the null terminator, that the value a number,
and that the pointer to the last char is not equal to the first (empty string passed) */
if (eptr[0] != '\0' || isnan(value) || (eptr[0] == ((char *)o->ptr)[0])) return C_ERR;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not keep the old string2d() which also uses fast_float_strtod()?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed. Addressed in de8b1be

@fcostaoliveira

Copy link
Copy Markdown
Collaborator

@sundb after rebasing from unstable and also doing the latest PR requests confirmed all improvements stay the same, with improvements reaching 26% on the achievable ops/sec (without pipelining) :

To replicate:

redis-benchmarks-spec-client-runner --tests-regexp "memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score|memtier_benchmark-1key-zset-100-elements-zrange-all-elements" --flushall_on_every_test_start --flushall_on_every_test_end  --cpuset_start_pos 2 --override-memtier-test-time 60

Results:

Test Name Metric unstable 9146ac0 this PR de8b1be % Change
memtier_benchmark-1key-zset-100-elements-zrange-all-elements Ops/sec 16710.92 21076.97 26.13%
memtier_benchmark-1key-zset-100-elements-zrange-all-elements p50 including RTT 9.343 7.583 18.84%
memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score Ops/sec 68801.57 86289.12 25.42%
memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score p50 including RTT 2.495 2.063 17.31%

@fcostaoliveira

fcostaoliveira commented Oct 19, 2024

Copy link
Copy Markdown
Collaborator

CE Performance Automation : step 2 of 2 (benchmark) FINISHED.

This comment was automatically generated given a benchmark was triggered.

Started benchmark suite at 2024-10-20 07:59:24.154571 and took 1.256626 seconds to finish.
Status: [################################################################################] 100.0% completed.

In total will run 1 benchmarks.
- 0 pending.
- 1 completed:
- 0 successful.
- 1 failed.
You can check a the status in detail via the grafana link

sundb added a commit that referenced this pull request Mar 19, 2025
#13845)

Since #11884, what was previously
accepted as a valid input (hexadecimal string) before 8.0 returned an
error. This PR addresses it. To avoid performance penalties if hints the
compiler that the fallbacks are not likely to happen.
Furthermore, we were ignoring std::result_out_of_range outputs from
fast_float. This PR addresses it as well and includes tests for both
identified scenarios.

---------

Co-authored-by: debing.sun <debing.sun@redis.com>
@sundb sundb added this to Redis 8.0 Aug 15, 2025
@sundb sundb moved this from Todo to Done in Redis 8.0 Aug 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

5 participants