Skip to content

Use Ryū's small feature to cut ~9kb #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 7, 2024
Merged

Use Ryū's small feature to cut ~9kb #55

merged 1 commit into from
Mar 7, 2024

Conversation

jbourassa
Copy link
Contributor

The ryu crate is used by serde_json to format floats when JSON encoding and when printing floats on JSON parse errors. The small feature reduces its binary size (it embeds a smaller table) at the cost of some performance. This change makes it so the "small" feature is used for Functions using this crate, shaving ~9kb.

Given dumping floats probably isn't the most frequent operation, and that the difference in performance is minimal (see below), this seems reasonable.

The caveat is that it doesn't look users can opt-in using the default features (i.e. []) of ryu, or at least, I couldn't figure out how. If we think this is problematic, we could update function-examples' Cargo.tomls to include the feature override.

The benchmark

$ cargo bench
running 16 tests
test bench_ryu::bench_0_f32         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_0_f64         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_e_f32         ... bench:          10 ns/iter (+/- 0)
test bench_ryu::bench_e_f64         ... bench:          15 ns/iter (+/- 7)
test bench_ryu::bench_max_f32       ... bench:          10 ns/iter (+/- 1)
test bench_ryu::bench_max_f64       ... bench:          22 ns/iter (+/- 1)
test bench_ryu::bench_short_f32     ... bench:          13 ns/iter (+/- 1)
test bench_ryu::bench_short_f64     ... bench:          26 ns/iter (+/- 1)
test bench_std_fmt::bench_0_f32     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_0_f64     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_e_f32     ... bench:          52 ns/iter (+/- 2)
test bench_std_fmt::bench_e_f64     ... bench:          58 ns/iter (+/- 0)
test bench_std_fmt::bench_max_f32   ... bench:          50 ns/iter (+/- 0)
test bench_std_fmt::bench_max_f64   ... bench:          74 ns/iter (+/- 4)
test bench_std_fmt::bench_short_f32 ... bench:          42 ns/iter (+/- 2)
test bench_std_fmt::bench_short_f64 ... bench:          41 ns/iter (+/- 0)

$ cargo bench --features small
running 16 tests
test bench_ryu::bench_0_f32         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_0_f64         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_e_f32         ... bench:          20 ns/iter (+/- 1)
test bench_ryu::bench_e_f64         ... bench:          20 ns/iter (+/- 1)
test bench_ryu::bench_max_f32       ... bench:          20 ns/iter (+/- 0)
test bench_ryu::bench_max_f64       ... bench:          20 ns/iter (+/- 2)
test bench_ryu::bench_short_f32     ... bench:          22 ns/iter (+/- 0)
test bench_ryu::bench_short_f64     ... bench:          31 ns/iter (+/- 2)
test bench_std_fmt::bench_0_f32     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_0_f64     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_e_f32     ... bench:          50 ns/iter (+/- 1)
test bench_std_fmt::bench_e_f64     ... bench:          55 ns/iter (+/- 3)
test bench_std_fmt::bench_max_f32   ... bench:          48 ns/iter (+/- 1)
test bench_std_fmt::bench_max_f64   ... bench:          74 ns/iter (+/- 0)
test bench_std_fmt::bench_short_f32 ... bench:          41 ns/iter (+/- 0)
test bench_std_fmt::bench_short_f64 ... bench:          40 ns/iter (+/- 0)

The ryu crate is used by serde_json to format floats when JSON encoding
and also when printing floats on JSON parse errors. The `small` feature
reduces its binary size (it embeds a smaller table) at the cost of some
performance.

9kb for Functions is a lot, dumping Float probably isn't the most
frequent operation, and the different is not massive at any rate: see
the table below for the difference between the 2 implementations.

This change makes it so the "small" feature is used in Functions.

```
$ cargo bench
running 16 tests
test bench_ryu::bench_0_f32         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_0_f64         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_e_f32         ... bench:          10 ns/iter (+/- 0)
test bench_ryu::bench_e_f64         ... bench:          15 ns/iter (+/- 7)
test bench_ryu::bench_max_f32       ... bench:          10 ns/iter (+/- 1)
test bench_ryu::bench_max_f64       ... bench:          22 ns/iter (+/- 1)
test bench_ryu::bench_short_f32     ... bench:          13 ns/iter (+/- 1)
test bench_ryu::bench_short_f64     ... bench:          26 ns/iter (+/- 1)
test bench_std_fmt::bench_0_f32     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_0_f64     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_e_f32     ... bench:          52 ns/iter (+/- 2)
test bench_std_fmt::bench_e_f64     ... bench:          58 ns/iter (+/- 0)
test bench_std_fmt::bench_max_f32   ... bench:          50 ns/iter (+/- 0)
test bench_std_fmt::bench_max_f64   ... bench:          74 ns/iter (+/- 4)
test bench_std_fmt::bench_short_f32 ... bench:          42 ns/iter (+/- 2)
test bench_std_fmt::bench_short_f64 ... bench:          41 ns/iter (+/- 0)

$ cargo bench --features small
running 16 tests
test bench_ryu::bench_0_f32         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_0_f64         ... bench:           1 ns/iter (+/- 0)
test bench_ryu::bench_e_f32         ... bench:          20 ns/iter (+/- 1)
test bench_ryu::bench_e_f64         ... bench:          20 ns/iter (+/- 1)
test bench_ryu::bench_max_f32       ... bench:          20 ns/iter (+/- 0)
test bench_ryu::bench_max_f64       ... bench:          20 ns/iter (+/- 2)
test bench_ryu::bench_short_f32     ... bench:          22 ns/iter (+/- 0)
test bench_ryu::bench_short_f64     ... bench:          31 ns/iter (+/- 2)
test bench_std_fmt::bench_0_f32     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_0_f64     ... bench:          11 ns/iter (+/- 0)
test bench_std_fmt::bench_e_f32     ... bench:          50 ns/iter (+/- 1)
test bench_std_fmt::bench_e_f64     ... bench:          55 ns/iter (+/- 3)
test bench_std_fmt::bench_max_f32   ... bench:          48 ns/iter (+/- 1)
test bench_std_fmt::bench_max_f64   ... bench:          74 ns/iter (+/- 0)
test bench_std_fmt::bench_short_f32 ... bench:          41 ns/iter (+/- 0)
test bench_std_fmt::bench_short_f64 ... bench:          40 ns/iter (+/- 0)
```
@jbourassa jbourassa requested a review from adampetro March 7, 2024 14:03
# Use the `small` feature of ryu (transitive dependency through serde_json)
# to shave off ~9kb of the Wasm binary size.
[dependencies.ryu]
version = "*"
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the thinking that by using *, cargo will use the same version that serde_json is using to avoid having multiple versions of ryu?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's the intent / hope. I think it works, but I'm no Cargo expert.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds reasonable

@jbourassa jbourassa merged commit 8b4860f into main Mar 7, 2024
@jbourassa jbourassa deleted the jb/small-ryu branch March 7, 2024 23:42
@jbourassa jbourassa mentioned this pull request Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants