Skip to content

Commit

Permalink
Merge pull request #146 from Alexhuszagh/itoa
Browse files Browse the repository at this point in the history
Increment the itoa benchmark versions.
  • Loading branch information
Alexhuszagh committed Sep 18, 2024
2 parents e2454cb + 7325f5f commit bb1cbf1
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 25 deletions.
77 changes: 63 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ High-performance numeric conversion routines for use in a `no_std` environment.

**Similar Projects**

If you want a minimal, stable, and compile-time friendly version of lexical's float-parsing algorithm, see [minimal-lexical](https://github.com/Alexhuszagh/minimal-lexical). If you want a minimal, performant float parser, recent versions of the Rust standard library should be [sufficient](https://github.com/rust-lang/rust/pull/86761).
If you want a minimal, stable, and compile-time friendly version of lexical's float-parsing algorithm, see [minimal-lexical](https://github.com/Alexhuszagh/minimal-lexical).

If you want a minimal, performant float parser, recent versions of the Rust standard library should be [sufficient](https://github.com/rust-lang/rust/pull/86761). For high-performance integer formatters, look at [itoa](https://docs.rs/itoa/latest/itoa/). The [metrics](#metrics) section contains a detailed comparison of various crates and their performance in comparison to lexical.

**Table of Contents**

Expand Down Expand Up @@ -263,7 +265,7 @@ Lexical is extensively used in production, the same float parsing algorithm has

## Metrics

Various benchmarks, binary sizes, and compile times are shown here:
Various benchmarks, binary sizes, and compile times are shown here. All the benchmarks can be found on [lexical-benchmarks](https://github.com/Alexhuszagh/lexical-benchmarks?tab=readme-ov-file#latest-results). All benchmarks used a black box to avoid optimizing out the result and leading to misleading metrics.

**Build Timings**

Expand All @@ -278,29 +280,76 @@ The binary sizes of stripped binaries compiled at optimization level "2". For a
![Parse Stripped - Optimization Level "2"](https://raw.githubusercontent.com/Alexhuszagh/rust-lexical/main/assets/size_parse_stripped_opt2_posix.svg)
![Write Stripped - Optimization Level "2"](https://raw.githubusercontent.com/Alexhuszagh/rust-lexical/main/assets/size_write_stripped_opt2_posix.svg)

**Benchmarks -- Parse Integer**
### Benchmarks — Parse Integer

**Random**

A benchmark on randomly-generated integers uniformly distributed over the entire range.

![Uniform Random Data](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/json_random%20-%20parse%20int%20-%20core,lexical.png)

**Simple**

A benchmark on randomly-generated integers from 1-1000.

![Simple Random Data](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/json_simple%20-%20parse%20int%20-%20core,lexical.png)

### Benchmarks — Parse Float

**Real-World Datasets**

A benchmark on parsing floats from various real-world data sets, including Canada, Mesh, and astronomical data (earth).

![Canada](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/canada%20-%20parse%20float%20-%20core,lexical.png)

![Earth](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/earth%20-%20parse%20float%20-%20core,lexical.png)

![Mesh](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/mesh%20-%20parse%20float%20-%20core,lexical.png)

**Random**

A benchmark on randomly-generated integers uniformly distributed over the entire range.

![Random Big Integer](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/random_big_ints%20-%20parse%20float%20-%20core,lexical.png)

**Simple**

A benchmark on randomly-generated integers from 1-1000.

![Random Simple](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/random_simple_int64%20-%20parse%20float%20-%20core,lexical.png)

### Benchmarks — Write Integer

**Random**

A benchmark on randomly-generated integers uniformly distributed over the entire range.

![Random Uniform](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/json_chain_random%20-%20write%20int%20-%20fmt,itoa,lexical.png)

**Simple**

![Random Simple](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/json_simple%20-%20write%20int%20-%20fmt,itoa,lexical.png)

A benchmark on randomly-generated integers uniformly distributed over the entire range. For a more fine-tuned breakdown, see [benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-integer/docs/Benchmarks.md).
**Large**

![Uniform Random Data](https://raw.githubusercontent.com/Alexhuszagh/rust-lexical/main/lexical-parse-integer/assets/random_uniform.svg)
![Random Large](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/random_large%20-%20write%20int%20-%20fmt,itoa,lexical.png)

**Benchmarks -- Parse Float**
### Benchmarks — Write Float

A benchmark on parsing floats from various real-world data sets. For a more fine-tuned breakdown, see [benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-float/docs/Benchmarks.md).
**Big Integer**

![Real Data](https://raw.githubusercontent.com/Alexhuszagh/rust-lexical/main/lexical-parse-float/assets/real.svg)
A benchmarks for values with a large integers.

**Benchmarks -- Write Integer**
![Big Integers](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/random_big_ints%20-%20write%20float%20-%20dtoa,fmt,lexical,ryu.png)

A benchmark on writing random integers uniformly distributed over the entire range. For a more fine-tuned breakdown, see [benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-write-integer/docs/Benchmarks.md).
**Simple 64-Bit Inteers**

![Uniform Random Data](https://raw.githubusercontent.com/Alexhuszagh/rust-lexical/main/lexical-write-integer/assets/random_uniform.svg)
![Simple Int64](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/random_simple_int64%20-%20write%20float%20-%20dtoa,fmt,lexical,ryu.png)

**Benchmarks -- Write Float**

A benchmark on writing floats generated via a random-number generator and parsed from a JSON document. For a more fine-tuned breakdown, see [benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-write-float/docs/Benchmarks.md).
**Random**

![Random Data](https://raw.githubusercontent.com/Alexhuszagh/rust-lexical/main/lexical-write-float/assets/json.svg)
![Random](https://github.com/Alexhuszagh/lexical-benchmarks/raw/main/results/da4728e/plot/json%20-%20write%20float%20-%20dtoa,fmt,lexical,ryu.png)

## Safety

Expand Down
9 changes: 2 additions & 7 deletions lexical-benchmark/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,16 +449,11 @@ macro_rules! ryu_generator {

macro_rules! itoa_generator {
($group:ident, $name:expr, $iter:expr) => {{
use lexical_util::constants::BUFFER_SIZE;
let mut buffer = vec![b'0'; BUFFER_SIZE];
let mut buffer = itoa::Buffer::new();
$group.bench_function($name, |bench| {
bench.iter(|| {
$iter.for_each(|&x| {
itoa::write(&mut buffer, x).unwrap();
black_box(&buffer);
unsafe {
buffer.set_len(0);
}
black_box(buffer.format(x));
})
})
});
Expand Down
3 changes: 2 additions & 1 deletion lexical-benchmark/parse-float/canada.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ fn canada(criterion: &mut Criterion) {
group.measurement_time(Duration::from_secs(5));

let data = input::read_lines("canada.txt");
parse_float_generator!(group, "canada", data.iter(), f64);
parse_float_generator!(group, "f32", data.iter(), f32);
parse_float_generator!(group, "f64", data.iter(), f64);
}

criterion_group!(canada_benches, canada);
Expand Down
3 changes: 2 additions & 1 deletion lexical-benchmark/parse-float/earth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ fn earth(criterion: &mut Criterion) {
group.measurement_time(Duration::from_secs(5));

let data = input::read_csv("earth.csv");
parse_float_generator!(group, "earth", data.iter(), f64);
parse_float_generator!(group, "f32", data.iter(), f32);
parse_float_generator!(group, "f64", data.iter(), f64);
}

criterion_group!(earth_benches, earth);
Expand Down
3 changes: 2 additions & 1 deletion lexical-benchmark/parse-float/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ fn mesh(criterion: &mut Criterion) {
group.measurement_time(Duration::from_secs(5));

let data = input::read_lines("mesh.txt");
parse_float_generator!(group, "mesh", data.iter(), f64);
parse_float_generator!(group, "f32", data.iter(), f32);
parse_float_generator!(group, "f64", data.iter(), f64);
}

criterion_group!(mesh_benches, mesh);
Expand Down
2 changes: 1 addition & 1 deletion lexical-benchmark/write-integer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ features = []

[dev-dependencies]
criterion = { version = "0.5.0", features = ["html_reports"] }
itoa = { version = "0.4", features = ["i128"] }
itoa = { version = "1.0.11" }
fastrand = "2.1.0"
lazy_static = "1"
serde = { version = "1.0", features = ["derive"] }
Expand Down

0 comments on commit bb1cbf1

Please sign in to comment.