Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8cf73d2
Convert html links to intra-doc links
dtolnay Feb 20, 2025
8558432
Point standard library links to stable
dtolnay Feb 20, 2025
12c70d0
Pin nightly toolchain used for miri job
dtolnay May 17, 2025
e11ae6f
Fix duplicated_attributes clippy lint in test
dtolnay Aug 8, 2025
d932895
Revert "Pin nightly toolchain used for miri job"
dtolnay Aug 8, 2025
d044880
Update actions/checkout@v4 -> v5
dtolnay Aug 23, 2025
5f39906
Opt in to generate-macro-expansion when building on docs.rs
dtolnay Sep 16, 2025
169491a
Fix unused assignment warning on vp /= 10
dtolnay Oct 13, 2025
bf5d462
Relocate clippy non_canonical_clone_impl suppression
dtolnay Oct 18, 2025
d3d3c67
Remove link to closed clippy issue
dtolnay Oct 18, 2025
7482445
Update actions/checkout@v5 -> v6
dtolnay Nov 20, 2025
cc09853
Resolve ptr_offset_by_literal pedantic clippy lints
dtolnay Dec 13, 2025
191f081
Ignore uninlined_format_args pedantic clippy lint in test
dtolnay Dec 14, 2025
c4fabbf
Raise required compiler to Rust 1.68
dtolnay Dec 14, 2025
bef7085
Update to 2021 edition
dtolnay Dec 14, 2025
851d0c5
Resolve uninlined_format_args pedantic clippy lint
dtolnay Dec 14, 2025
e53cd22
Switch from test::black_box to std::hint::black_box
dtolnay Dec 19, 2025
f0adb29
Benchmark using e from consts module
dtolnay Dec 19, 2025
37096b0
Switch from cargo bench to criterion
dtolnay Dec 19, 2025
c953bd4
Raise minimum tested compiler to rust 1.86
dtolnay Dec 19, 2025
e867bd5
Update actions/upload-artifact@v4 -> v5
dtolnay Dec 19, 2025
13cef56
Update actions/upload-artifact@v5 -> v6
dtolnay Dec 20, 2025
5bb791b
Remove supported compiler version statement from readme
dtolnay Dec 20, 2025
7fd9217
Exclude benchmark dependencies from being compiled by miri
dtolnay Dec 21, 2025
ca2c772
Fix stacked borrows violation in test_exhaustive
dtolnay Dec 23, 2025
ba346b9
Switch to fixed size counters
dtolnay Dec 23, 2025
a63105b
Resolve cast_lossless pedantic clippy lint in test
dtolnay Dec 23, 2025
301f0bc
Support platform without 64-bit atomic
dtolnay Dec 23, 2025
b37156e
Add miri architecture matrix
dtolnay Dec 23, 2025
e8f2b6d
Remove clippy suppression that is no longer triggered
dtolnay Dec 24, 2025
f2c9600
Delete f32 from fuzz target
dtolnay Dec 24, 2025
584d51d
Add static assertion on static table size
dtolnay Dec 25, 2025
dd98e63
Use performance chart from dtoa-benchmark
dtolnay Dec 27, 2025
8847422
Exclude dtoa-benchmark.png from published crate
dtolnay Dec 27, 2025
03e2f06
Delete old chart code
dtolnay Dec 27, 2025
fa0d87e
Sync to ulfjack/ryu@1264a94
dtolnay Dec 28, 2025
9d9eb02
Switch to 9975WX benchmark data
dtolnay Jan 17, 2026
a776e03
Sync to ulfjack/ryu@e3e090c
dtolnay Jan 23, 2026
fe4b150
Ignore rand_xorshift 0.5.0 until release of rand 0.10.0
dtolnay Feb 3, 2026
fdc45d5
Update rand_xorshift dev-dependency to 0.5 release candidate
dtolnay Feb 3, 2026
1c66d18
Update rand from 0.9 to 0.10
dtolnay Feb 8, 2026
90ee903
Raise required compiler to Rust 1.71
dtolnay Feb 8, 2026
8530d61
Pin CI miri to nightly-2026-02-11
dtolnay Feb 12, 2026
501aecd
Unpin CI miri toolchain
dtolnay Feb 16, 2026
50fef34
Fix cargo clippy warnings
jedel1043 Feb 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
msrv = "1.64.0"
msrv = "1.71.0"
42 changes: 28 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,36 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: [nightly, beta, stable]
rust: [nightly, beta, stable, 1.86.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
- name: Enable type layout randomization
run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV
if: matrix.rust == 'nightly'
- run: cargo build
- run: cargo test
- run: cargo build --features small
- run: cargo test --features small
- run: cargo build --tests --features no-panic --release
if: matrix.rust == 'nightly'
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v6
if: matrix.rust == 'nightly' && always()
with:
name: Cargo.lock
path: Cargo.lock
continue-on-error: true

msrv:
name: Rust 1.64.0
name: Rust 1.71.0
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.64.0
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@1.71.0
- run: cargo build
- run: cargo build --features small

Expand All @@ -63,20 +65,32 @@ jobs:
env:
RUSTDOCFLAGS: -Dwarnings
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/install@cargo-docs-rs
- run: cargo docs-rs

miri:
name: Miri
name: Miri (${{matrix.name}})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: 64-bit little endian
target: x86_64-unknown-linux-gnu
- name: 64-bit big endian
target: powerpc64-unknown-linux-gnu
- name: 32-bit little endian
target: i686-unknown-linux-gnu
- name: 32-bit big endian
target: mips-unknown-linux-gnu
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@miri
- run: cargo miri setup
- run: cargo miri test
- run: cargo miri test --target ${{matrix.target}}
env:
MIRIFLAGS: -Zmiri-strict-provenance

Expand All @@ -85,7 +99,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@clippy
- run: cargo clippy --tests --benches -- -Dclippy::all -Dclippy::pedantic

Expand All @@ -94,18 +108,18 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/install@cargo-outdated
- run: cargo outdated --workspace --exit-code 1
- run: cargo outdated --workspace --ignore rand,rand_core,rand_xorshift --exit-code 1
- run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1

fuzz:
name: Fuzz
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/install@cargo-fuzz
- run: cargo fuzz check
31 changes: 20 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ authors = ["David Tolnay <dtolnay@gmail.com>", "boa-dev"]
categories = ["value-formatting", "no-std", "no-std::no-alloc"]
description = "Fast floating point to string conversion, ECMAScript compliant."
documentation = "https://docs.rs/ryu-js"
edition = "2018"
exclude = ["build.rs", "performance.png", "chart/**"]
edition = "2021"
exclude = ["build.rs", "*.png"]
keywords = ["float"]
license = "Apache-2.0 OR BSL-1.0"
repository = "https://github.com/boa-dev/ryu-js"
rust-version = "1.64"
rust-version = "1.71"

[features]
# Use smaller lookup tables. Instead of storing every required power of
Expand All @@ -24,19 +24,28 @@ no-panic = { version = "0.1", optional = true }

[dev-dependencies]
num_cpus = "1.8"
rand = "0.9"
rand_xorshift = "0.4"
criterion = "0.5"
rand = "0.10"
rand_core = "0.10"
rand_xorshift = "0.5"

[target.'cfg(not(miri))'.dev-dependencies]
criterion = { version = "0.8", default-features = false }

[lib]
bench = false

[[bench]]
name = "bench"
harness = false

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

# See: https://github.com/rust-lang/rust/pull/84176
rustdoc-args = ["--generate-link-to-definition"]

[[bench]]
name = "bench"
harness = false
rustdoc-args = [
"--generate-link-to-definition",
"--generate-macro-expansion",
"--extern-html-root-url=core=https://doc.rust-lang.org",
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
"--extern-html-root-url=std=https://doc.rust-lang.org",
]
15 changes: 2 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ under the creative commons CC-BY-SA license.
This Rust implementation is a line-by-line port of Ulf Adams' implementation in
C, [https://github.com/ulfjack/ryu][upstream].

*Requirements: This crate supports any compiler version back to rustc 1.64; it
uses nothing from the Rust standard library so is usable from no_std crates.*

[paper]: https://dl.acm.org/citation.cfm?id=3192369
[upstream]: https://github.com/ulfjack/ryu/tree/abf76d252bc97300354857e64e80d4a2bf664291
[upstream]: https://github.com/ulfjack/ryu/tree/e3e090c66efd258a0cee50ee93411ec99668d416

```toml
[dependencies]
Expand All @@ -39,15 +36,7 @@ fn main() {
}
```

## Performance

<!--

## Performance (lower is better)

![performance](https://raw.githubusercontent.com/boa-dev/ryu-js/master/performance.png)

-->
## Performance

You can run upstream's benchmarks with:

Expand Down
89 changes: 36 additions & 53 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,42 @@
// cargo bench

#![allow(
clippy::approx_constant,
clippy::excessive_precision,
clippy::unreadable_literal
)]

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{criterion_group, criterion_main, Criterion};
use std::fmt::Display;
use std::hint;
use std::io::Write;
use std::{f32, f64};

macro_rules! benches {
($($name:ident($value:expr),)*) => {
mod bench_ryu_js {
use super::*;
$(
pub fn $name(c: &mut Criterion) {
let mut buf = ryu_js::Buffer::new();

c.bench_function(concat!("ryu_js_", stringify!($name)), move |b| b.iter(move || {
let value = black_box($value);
let formatted = buf.format_finite(value);
black_box(formatted);
}));
}
)*
}
criterion_group!(bench_ryu_js, $( bench_ryu_js::$name, )*);
fn do_bench(c: &mut Criterion, group_name: &str, float: impl ryu_js::Float + Display) {
let mut group = c.benchmark_group(group_name);
group.bench_function("ryu_js", |b| {
let mut buf = ryu_js::Buffer::new();
b.iter(move || {
let float = hint::black_box(float);
let formatted = buf.format_finite(float);
hint::black_box(formatted);
});
});
group.bench_function("std::fmt", |b| {
let mut buf = Vec::with_capacity(20);
b.iter(|| {
buf.clear();
let float = hint::black_box(float);
write!(&mut buf, "{float}").unwrap();
hint::black_box(buf.as_slice());
});
});
group.finish();
}

mod bench_std_fmt {
use super::*;
$(
pub fn $name(c: &mut Criterion) {
let mut buf = Vec::with_capacity(20);
fn bench(c: &mut Criterion) {
do_bench(c, "f64[0]", 0f64);
do_bench(c, "f64[short]", 0.1234f64);
do_bench(c, "f64[e]", f64::consts::E);
do_bench(c, "f64[max]", f64::MAX);

c.bench_function(concat!("std_fmt_", stringify!($name)), move |b| b.iter(|| {
buf.clear();
let value = black_box($value);
write!(&mut buf, "{}", value).unwrap();
black_box(buf.as_slice());
}));
}
)*
}
criterion_group!(bench_std_fmt, $( bench_std_fmt::$name, )*);
criterion_main!(bench_ryu_js, bench_std_fmt);
};
do_bench(c, "f32[0]", 0f32);
do_bench(c, "f32[short]", 0.1234f32);
do_bench(c, "f32[e]", f32::consts::E);
do_bench(c, "f32[max]", f32::MAX);
}

benches! {
bench_0_f64(0_f64),
bench_short_f64(0.1234_f64),
bench_e_f64(2.718281828459045_f64),
bench_max_f64(f64::MAX),
bench_0_f32(0_f32),
bench_short_f32(0.1234_f32),
bench_e_f32(2.718281828459045_f32),
bench_max_f32(f32::MAX),
}
criterion_group!(benches, bench);
criterion_main!(benches);
7 changes: 0 additions & 7 deletions chart/.gitignore

This file was deleted.

80 changes: 0 additions & 80 deletions chart/performance.tex

This file was deleted.

Binary file added dtoa-benchmark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/upstream_benchmark.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// cargo run --example upstream_benchmark --release

use rand::{Rng, SeedableRng};
use rand::{RngExt as _, SeedableRng as _};

const SAMPLES: usize = 10000;
const ITERATIONS: usize = 1000;
Expand Down
Loading
Loading