Yi Kong | ce81bb6 | 2020-08-31 01:21:33 +0800 | [diff] [blame^] | 1 | # Ryū |
| 2 | |
| 3 | [<img alt="github" src="https://img.shields.io/badge/github-dtolnay/ryu-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/ryu) |
| 4 | [<img alt="crates.io" src="https://img.shields.io/crates/v/ryu.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/ryu) |
| 5 | [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-ryu-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/ryu) |
| 6 | [<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/ryu/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/ryu/actions?query=branch%3Amaster) |
| 7 | |
| 8 | Pure Rust implementation of Ryū, an algorithm to quickly convert floating point |
| 9 | numbers to decimal strings. |
| 10 | |
| 11 | The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf Adams |
| 12 | includes a complete correctness proof of the algorithm. The paper is available |
| 13 | under the creative commons CC-BY-SA license. |
| 14 | |
| 15 | This Rust implementation is a line-by-line port of Ulf Adams' implementation in |
| 16 | C, [https://github.com/ulfjack/ryu][upstream]. |
| 17 | |
| 18 | *Requirements: this crate supports any compiler version back to rustc 1.31; it |
| 19 | uses nothing from the Rust standard library so is usable from no_std crates.* |
| 20 | |
| 21 | [paper]: https://dl.acm.org/citation.cfm?id=3192369 |
| 22 | [upstream]: https://github.com/ulfjack/ryu/tree/1c413e127f8d02afd12eb6259bc80163722f1385 |
| 23 | |
| 24 | ```toml |
| 25 | [dependencies] |
| 26 | ryu = "1.0" |
| 27 | ``` |
| 28 | |
| 29 | ## Example |
| 30 | |
| 31 | ```rust |
| 32 | fn main() { |
| 33 | let mut buffer = ryu::Buffer::new(); |
| 34 | let printed = buffer.format(1.234); |
| 35 | assert_eq!(printed, "1.234"); |
| 36 | } |
| 37 | ``` |
| 38 | |
| 39 | ## Performance |
| 40 | |
| 41 | You can run upstream's benchmarks with: |
| 42 | |
| 43 | ```console |
| 44 | $ git clone https://github.com/ulfjack/ryu c-ryu |
| 45 | $ cd c-ryu |
| 46 | $ bazel run -c opt //ryu/benchmark |
| 47 | ``` |
| 48 | |
| 49 | And the same benchmark against our implementation with: |
| 50 | |
| 51 | ```console |
| 52 | $ git clone https://github.com/dtolnay/ryu rust-ryu |
| 53 | $ cd rust-ryu |
| 54 | $ cargo run --example upstream_benchmark --release |
| 55 | ``` |
| 56 | |
| 57 | These benchmarks measure the average time to print a 32-bit float and average |
| 58 | time to print a 64-bit float, where the inputs are distributed as uniform random |
| 59 | bit patterns 32 and 64 bits wide. |
| 60 | |
| 61 | The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API |
| 62 | all perform the same, taking around 21 nanoseconds to format a 32-bit float and |
| 63 | 31 nanoseconds to format a 64-bit float. |
| 64 | |
| 65 | There is also a Rust-specific benchmark comparing this implementation to the |
| 66 | standard library which you can run with: |
| 67 | |
| 68 | ```console |
| 69 | $ cargo bench |
| 70 | ``` |
| 71 | |
| 72 | The benchmark shows Ryū approximately 4-10x faster than the standard library |
| 73 | across a range of f32 and f64 inputs. Measurements are in nanoseconds per |
| 74 | iteration; smaller is better. |
| 75 | |
| 76 | | type=f32 | 0.0 | 0.1234 | 2.718281828459045 | f32::MAX | |
| 77 | |:--------:|:----:|:------:|:-----------------:|:--------:| |
| 78 | | RYU | 3ns | 28ns | 23ns | 22ns | |
| 79 | | STD | 40ns | 106ns | 128ns | 110ns | |
| 80 | |
| 81 | | type=f64 | 0.0 | 0.1234 | 2.718281828459045 | f64::MAX | |
| 82 | |:--------:|:----:|:------:|:-----------------:|:--------:| |
| 83 | | RYU | 3ns | 50ns | 35ns | 32ns | |
| 84 | | STD | 39ns | 105ns | 128ns | 202ns | |
| 85 | |
| 86 | ## Formatting |
| 87 | |
| 88 | This library tends to produce more human-readable output than the standard |
| 89 | library's to\_string, which never uses scientific notation. Here are two |
| 90 | examples: |
| 91 | |
| 92 | - *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000 |
| 93 | - *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123 |
| 94 | |
| 95 | Both libraries print short decimals such as 0.0000123 without scientific |
| 96 | notation. |
| 97 | |
| 98 | <br> |
| 99 | |
| 100 | #### License |
| 101 | |
| 102 | <sup> |
| 103 | Licensed under either of <a href="LICENSE-APACHE">Apache License, Version |
| 104 | 2.0</a> or <a href="LICENSE-BOOST">Boost Software License 1.0</a> at your |
| 105 | option. |
| 106 | </sup> |
| 107 | |
| 108 | <br> |
| 109 | |
| 110 | <sub> |
| 111 | Unless you explicitly state otherwise, any contribution intentionally submitted |
| 112 | for inclusion in this crate by you, as defined in the Apache-2.0 license, shall |
| 113 | be dual licensed as above, without any additional terms or conditions. |
| 114 | </sub> |