{"id":13822426,"url":"https://github.com/aldanor/fast-float-rust","last_synced_at":"2025-05-16T04:07:11.649Z","repository":{"id":45032434,"uuid":"325561717","full_name":"aldanor/fast-float-rust","owner":"aldanor","description":"Super-fast float parser in Rust (now part of Rust core)","archived":false,"fork":false,"pushed_at":"2022-12-02T03:55:32.000Z","size":229,"stargazers_count":273,"open_issues_count":6,"forks_count":19,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-08T14:11:55.785Z","etag":null,"topics":["floating-point","high-performance","parser","rust"],"latest_commit_sha":null,"homepage":"https://docs.rs/fast-float","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aldanor.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-30T13:46:20.000Z","updated_at":"2025-03-04T10:12:19.000Z","dependencies_parsed_at":"2023-01-23T06:00:10.308Z","dependency_job_id":null,"html_url":"https://github.com/aldanor/fast-float-rust","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldanor%2Ffast-float-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldanor%2Ffast-float-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldanor%2Ffast-float-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldanor%2Ffast-float-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aldanor","download_url":"https://codeload.github.com/aldanor/fast-float-rust/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254464897,"owners_count":22075571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["floating-point","high-performance","parser","rust"],"created_at":"2024-08-04T08:01:59.729Z","updated_at":"2025-05-16T04:07:06.640Z","avatar_url":"https://github.com/aldanor.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"fast-float\n==========\n\n[![Build](https://github.com/aldanor/fast-float-rust/workflows/CI/badge.svg)](https://github.com/aldanor/fast-float-rust/actions?query=branch%3Amaster)\n[![Latest Version](https://img.shields.io/crates/v/fast-float.svg)](https://crates.io/crates/fast-float)\n[![Documentation](https://docs.rs/fast-float/badge.svg)](https://docs.rs/fast-float)\n[![Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Rustc 1.37+](https://img.shields.io/badge/rustc-1.37+-lightgray.svg)](https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html)\n\nThis crate provides a super-fast decimal number parser from strings into floats.\n\n```toml\n[dependencies]\nfast-float = \"0.2\"\n```\n\nThere are no dependencies and the crate can be used in a no_std context by disabling the \"std\" feature.\n\n*Compiler support: rustc 1.37+.*\n\n## Usage\n\nThere's two top-level functions provided: \n[`parse()`](https://docs.rs/fast-float/latest/fast_float/fn.parse.html) and \n[`parse_partial()`](https://docs.rs/fast-float/latest/fast_float/fn.parse_partial.html), both taking\neither a string or a bytes slice and parsing the input into either `f32` or `f64`: \n\n- `parse()` treats the whole string as a decimal number and returns an error if there are\n  invalid characters or if the string is empty.\n- `parse_partial()` tries to find the longest substring at the beginning of the given input\n  string that can be parsed as a decimal number and, in the case of success, returns the parsed\n  value along the number of characters processed; an error is returned if the string doesn't\n  start with a decimal number or if it is empty. This function is most useful as a building\n  block when constructing more complex parsers, or when parsing streams of data.\n\nExample:\n\n```rust\n// Parse the entire string as a decimal number.\nlet s = \"1.23e-02\";\nlet x: f32 = fast_float::parse(s).unwrap();\nassert_eq!(x, 0.0123);\n\n// Parse as many characters as possible as a decimal number.\nlet s = \"1.23e-02foo\";\nlet (x, n) = fast_float::parse_partial::\u003cf32, _\u003e(s).unwrap();\nassert_eq!(x, 0.0123);\nassert_eq!(n, 8);\nassert_eq!(\u0026s[n..], \"foo\");\n```\n\n## Details\n\nThis crate is a direct port of Daniel Lemire's [`fast_float`](https://github.com/fastfloat/fast_float)\nC++ library (valuable discussions with Daniel while porting it helped shape the crate and get it to \nthe performance level it's at now), with some Rust-specific tweaks. Please see the original\nrepository for many useful details regarding the algorithm and the implementation.\n\nThe parser is locale-independent. The resulting value is the closest floating-point values (using either \n`f32` or `f64`), using the \"round to even\" convention for values that would otherwise fall right in-between \ntwo values. That is, we provide exact parsing according to the IEEE standard. \n\nInfinity and NaN values can be parsed, along with scientific notation.\n\nBoth little-endian and big-endian platforms are equally supported, with extra optimizations enabled\non little-endian architectures.\n\n## Testing\n\nThere are a few ways this crate is tested:\n\n- A suite of explicit tests (taken from the original library) covering lots of edge cases.\n- A file-based test suite (taken from the original library; credits to Nigel Tao), ~5M tests.\n- All 4B float32 numbers are exhaustively roundtripped via ryu formatter.\n- Roundtripping a large quantity of random float64 numbers via ryu formatter.\n- Roundtripping float64 numbers and fuzzing random input strings via cargo-fuzz.\n- All explicit test suites run on CI; roundtripping and fuzzing are run manually.\n\n## Performance\n\nThe presented parser seems to beat all of the existing C/C++/Rust float parsers known to us at the\nmoment by a large margin, in all of the datasets we tested it on so far – see detailed benchmarks \nbelow (the only exception being the original fast_float C++ library, of course – performance of\nwhich is within noise bounds of this crate). On modern machines like Apple M1, parsing throughput\ncan reach up to 1.5 GB/s.\n\nIn particular, it is faster than Rust standard library's `FromStr::from_str()` by a factor of 2-8x\n(larger factor for longer float strings), and is typically 2-3x faster than the nearest competitors.\n\nWhile various details regarding the algorithm can be found in the repository for the original\nC++ library, here are few brief notes:\n\n- The parser is specialized to work lightning-fast on inputs with at most 19 significant digits\n  (which constitutes the so called \"fast-path\"). We believe that most real-life inputs should\n  fall under this category, and we treat longer inputs as \"degenerate\" edge cases since it\n  inevitable causes overflows and loss of precision.\n- If the significand happens to be longer than 19 digits, the parser falls back to the \"slow path\",\n  in which case its performance roughly matches that of the top Rust/C++ libraries (and still\n  beats them most of the time, although not by a lot).\n- On little-endian systems, there's additional optimizations for numbers with more than 8 digits\n  after the decimal point.\n\n## Benchmarks\n\nBelow are tables of best timings in nanoseconds for parsing a single number \ninto a 64-bit float.\n\n#### Intel i7-4771\n\nIntel i7-4771 3.5GHz, macOS, Rust 1.49.\n\n|                  | `canada` | `mesh`   | `uniform` | `iidi` | `iei`  | `rec32` |\n| ---------------- | -------- | -------- | --------- | ------ | ------ | ------- |\n| fast-float       | 21.58    | 10.70    | 19.36     | 40.50  | 26.07  | 29.13   |\n| lexical          | 65.90    | 23.28    | 54.75     | 75.80  | 52.18  | 75.36   |\n| from_str         | 174.43   | 22.30    | 99.93     | 227.76 | 111.31 | 204.46  |\n| fast_float (C++) | 22.78    | 10.99    | 20.05     | 41.12  | 27.51  | 30.85   |\n| abseil (C++)     | 42.66    | 32.88    | 46.01     | 50.83  | 46.33  | 49.95   |\n| netlib (C)       | 57.53    | 24.86    | 64.72     | 56.63  | 36.20  | 67.29   |\n| strtod (C)       | 286.10   | 31.15    | 258.73    | 295.73 | 205.72 | 315.95  |\n\n#### Apple M1\n\nApple M1, macOS, Rust 1.49.\n\n|                  | `canada` | `mesh`   | `uniform` | `iidi` | `iei`  | `rec32` |\n| ---------------- | -------- | -------- | --------- | ------ | ------ | ------- |\n| fast-float       | 14.84    | 5.98     | 11.24     | 33.24  | 21.30  | 17.86   |\n| lexical          | 47.09    | 16.51    | 43.46     | 56.06  | 36.68  | 55.48   |\n| from_str         | 136.00   | 13.84    | 74.64     | 179.87 | 77.91  | 154.53  |\n| fast_float (C++) | 13.71    | 7.28     | 11.71     | 32.94  | 20.64  | 18.30   |\n| abseil (C++)     | 36.55    | 24.20    | 38.48     | 40.86  | 35.46  | 40.09   |\n| netlib (C)       | 47.19    | 14.12    | 48.85     | 52.28  | 33.70  | 48.79   |\n| strtod (C)       | 176.13   | 21.48    | 165.43    | 187.98 | 132.19 | 190.63  |\n\n#### AMD Rome\n\nAMD Rome, Linux, Rust 1.49.\n\n|                  | `canada` | `mesh`   | `uniform` | `iidi` | `iei`  | `rec32` |\n| ---------------- | -------- | -------- | --------- | ------ | ------ | ------- |\n| fast-float       | 25.90    | 12.12    | 20.54     | 47.01  | 29.23  | 32.36   |\n| lexical          | 63.18    | 22.13    | 54.78     | 81.23  | 55.06  | 79.14   |\n| from_str         | 190.06   | 26.10    | 102.44    | 239.87 | 119.04 | 211.73  |\n| fast_float (C++) | 21.29    | 10.47    | 18.31     | 42.33  | 24.56  | 29.76   |\n| abseil (C++)     | 44.54    | 34.13    | 47.38     | 52.64  | 43.77  | 53.03   |\n| netlib (C)       | 69.43    | 23.31    | 79.98     | 72.17  | 35.81  | 86.91   |\n| strtod (C)       | 123.37   | 65.68    | 101.58    | 118.36 | 118.61 | 123.72  |\n\n#### Parsers\n\n- `fast-float` - this very crate\n- `lexical` – `lexical_core`, v0.7 (non-lossy; same performance as lossy)\n- `from_str` – Rust standard library, `FromStr` trait\n- `fast_float (C++)` – original C++ implementation of 'fast-float' method\n- `abseil (C++)` – Abseil C++ Common Libraries\n- `netlib (C++)` – C++ Network Library\n- `strtod (C)` – C standard library\n\n#### Datasets\n\n- `canada` – numbers in `canada.txt` file\n- `mesh` – numbers in `mesh.txt` file\n- `uniform` – uniform random numbers from 0 to 1\n- `iidi` – random numbers of format `%d%d.%d`\n- `iei` – random numbers of format `%de%d`\n- `rec32` – reciprocals of random 32-bit integers\n\n#### Notes\n\n- The two test files referred above can be found in \n[this](https://github.com/lemire/simple_fastfloat_benchmark) repository.\n- The Rust part of the table (along with a few other benchmarks) can be generated via\n  the benchmark tool that can be found under `extras/simple-bench` of this repo.\n- The C/C++ part of the table (along with a few other benchmarks and parsers) can be\n  generated via a C++ utility that can be found in \n  [this](https://github.com/lemire/simple_fastfloat_benchmark) repository.\n\n\u003cbr\u003e\n\n#### References\n\n- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Practice and Experience 51 (8), 2021.\n\n#### License\n\n\u003csup\u003e\nLicensed under either of \u003ca href=\"LICENSE-APACHE\"\u003eApache License, Version\n2.0\u003c/a\u003e or \u003ca href=\"LICENSE-MIT\"\u003eMIT license\u003c/a\u003e at your option.\n\u003c/sup\u003e\n\n\u003cbr\u003e\n\n\u003csub\u003e\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faldanor%2Ffast-float-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faldanor%2Ffast-float-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faldanor%2Ffast-float-rust/lists"}