0.2.x benchmarks fix (#328)
* Fix benchmark measurement (#279)
* Run setup for every iteration of the benchmark
* Fix clippy inline formatting warning
* Cargo fmt
* Update README with corrected results
* Reinstate 1_000_000 node benchmark
* Rustfmt
* Update benchmark results
* Update benchmark description
* Gitignore file names ending in -test-names.txt
456653c2c618ea2b3390c4d717c38edbdf684ae4 · by Nico Burns · (3 years ago) · parent df9799325 · browse the tree at this commit
diff --git a/.gitignore b/.gitignore
index 5188ccbf6..d70fe4b5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ Cargo.lock
.DS_Store
.vscode
+
+*-test-names.txt
\ No newline at end of file
diff --git a/README.md b/README.md
index d6e8cb8d0..f3be022ce 100644
--- a/README.md
+++ b/README.md
@@ -76,11 +76,11 @@ assert_eq!(taffy.layout(body_node).unwrap().size.height, 500.0); // This value w
| Benchmark | Yoga | Taffy 0.2 |
| --- | --- | --- |
-| yoga/10 nodes (1-level hierarchy) | 45.1670 µs | 33.297 ns |
-| yoga/100 nodes (2-level hierarchy) | 134.1250 µs | 336.53 ns |
-| yoga/1_000 nodes (3-level hierarchy) | 1.2221 ms | 3.8928 µs |
-| yoga/10_000 nodes (4-level hierarchy) | 13.8672 ms | 36.162 µs |
-| yoga/100_000 nodes (5-level hierarchy) | 141.5307 ms | 1.6404 ms |
+| yoga/10 nodes (1-level hierarchy) | 45.1670 µs | 1.9857 µs |
+| yoga/100 nodes (2-level hierarchy) | 134.1250 µs | 41.810 µs |
+| yoga/1_000 nodes (3-level hierarchy) | 1.2221 ms | 357.48 µs |
+| yoga/10_000 nodes (4-level hierarchy) | 13.8672 ms | 3.7310 ms |
+| yoga/100_000 nodes (5-level hierarchy) | 141.5307 ms | 39.682 ms |
Most popular websites seem to have between 3,000 and 10,000 nodes (although they also require text layout, which neither yoga nor taffy implement).
diff --git a/benches/big_tree.rs b/benches/big_tree.rs
index 5118593d4..fda359e75 100644
--- a/benches/big_tree.rs
+++ b/benches/big_tree.rs
@@ -87,39 +87,75 @@ fn taffy_benchmarks(c: &mut Criterion) {
group.sample_size(10);
group.bench_function("10 nodes", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 10, 10);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_yoga_deep_hierarchy(&mut taffy, 10, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("100 nodes", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 100, 10);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_yoga_deep_hierarchy(&mut taffy, 100, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("1_000 nodes", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 1_000, 10);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_yoga_deep_hierarchy(&mut taffy, 1_000, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("10_000 nodes", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 10_000, 10);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_yoga_deep_hierarchy(&mut taffy, 10_000, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("100_000 nodes", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 100_000, 10);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_yoga_deep_hierarchy(&mut taffy, 100_000, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
group.bench_function("1_000_000 nodes", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 1_000_000, 10);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_yoga_deep_hierarchy(&mut taffy, 1_000_000, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
drop(group);
@@ -128,45 +164,75 @@ fn taffy_benchmarks(c: &mut Criterion) {
group.sample_size(10);
group.bench_function("10 nodes (2-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_flat_hierarchy(&mut taffy, 10);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_flat_hierarchy(&mut taffy, 10);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("100 nodes (2-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_flat_hierarchy(&mut taffy, 100);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_flat_hierarchy(&mut taffy, 100);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("1_000 nodes (2-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_flat_hierarchy(&mut taffy, 1_000);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_flat_hierarchy(&mut taffy, 1_000);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("10_000 nodes (2-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_flat_hierarchy(&mut taffy, 10_000);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_flat_hierarchy(&mut taffy, 10_000);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
group.bench_function("100_000 nodes (2-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_flat_hierarchy(&mut taffy, 100_000);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_flat_hierarchy(&mut taffy, 100_000);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
group.bench_function("100_000 nodes (7-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_deep_hierarchy(&mut taffy, 100_000, 7);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 100_000, 7);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
drop(group);
@@ -176,31 +242,51 @@ fn taffy_benchmarks(c: &mut Criterion) {
group.sample_size(10);
group.bench_function("4000 nodes (12-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_deep_hierarchy(&mut taffy, 4000, 2);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 4000, 2);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("10_000 nodes (14-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_deep_hierarchy(&mut taffy, 10_000, 2);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 10_000, 2);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("100_000 nodes (17-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_deep_hierarchy(&mut taffy, 100_000, 2);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 100_000, 2);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
group.bench_function("1_000_000 nodes (20-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_deep_hierarchy(&mut taffy, 1_000_000, 2);
-
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 1_000_000, 2);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::LargeInput,
+ )
});
drop(group);
@@ -209,15 +295,27 @@ fn taffy_benchmarks(c: &mut Criterion) {
group.sample_size(10);
group.bench_function("100 nodes (100-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 100, 1);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 100, 1);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
group.bench_function("1_000 nodes (1000-level hierarchy)", |b| {
- let mut taffy = Taffy::new();
- let root = build_yoga_deep_hierarchy(&mut taffy, 1_000, 1);
- b.iter(|| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap())
+ b.iter_batched(
+ || {
+ let mut taffy = Taffy::new();
+ let root = build_deep_hierarchy(&mut taffy, 1_000, 1);
+ (taffy, root)
+ },
+ |(mut taffy, root)| taffy.compute_layout(root, Size::MAX_CONTENT).unwrap(),
+ criterion::BatchSize::SmallInput,
+ )
});
}
diff --git a/benches/results-2022-11-23.md b/benches/results-2022-11-23.md
deleted file mode 100644
index b00cff9fe..000000000
--- a/benches/results-2022-11-23.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Benchmarks (Taffy 0.2 vs Taffy 0.1 and Yoga)
-
-- Using [this branch](https://github.com/nicoburns/taffy/tree/0.1-benchmarks) that backports the new benchmarks to the `0.1` tag.
-- Run on a 2021 MacBook Pro with M1 Pro processor.
-- Taffy benchmarks are using criterion (10 iterations).
-- Yoga benchmarks run via the `yoga-layout-prebuilt` npm package, they were run a few times manually and it was verified that variance in the numbers of each run was minimal. It should be noted that this is using an old version of Yoga.
-
-| Benchmark | Yoga | Taffy 0.1 | Taffy 0.2 | % change (0.1 -> 0.2) |
-| --- | --- | --- | --- | --- |
-| yoga/10 nodes (1-level hierarchy) | 45.1670 µs | 68.499 ns | 33.297 ns | -51.161% |
-| yoga/100 nodes (2-level hierarchy) | 134.1250 µs | 378.22 ns | 336.53 ns | -10.862% |
-| yoga/1_000 nodes (3-level hierarchy) | 1.2221 ms | 3.2015 µs | 3.8928 µs | +21.080% |
-| yoga/10_000 nodes (4-level hierarchy) | 13.8672 ms | 37.347 µs | 36.162 µs | -11.971% |
-| yoga/100_000 nodes (5-level hierarchy) | 141.5307 ms | 1.5660 s | 1.6404 ms | -99.890% |
-| yoga /1_000_000 nodes (6-level hierarchy) | - | - | 50.760 ms | - |
-| wide/10 nodes (2-level hierarchy) | - | 73.037 ns | 41.936 ns | -41.936% |
-| wide/100 nodes (2-level hierarchy) | - | 371.70 ns | 309.37 ns | -16.605% |
-| wide/1_000 nodes (2-level hierarchy) | - | 3.5458 µs | 4.3571 µs | +23.333% |
-| wide/10_000 nodes (2-level hierarchy) | - | 36.418 µs | 42.967 µs | +17.357% |
-| wide/100_000 nodes (2-level hierarchy) | - | 1.8275 ms | 3.9096 ms | +112.26% |
-| semi-wide/100_000 nodes (7-level hierarchy) | - | 2.6569 s | 1.4992 ms | -99.933% |
-| deep/4000 nodes (12-level hierarchy)) | - | 5.1845 s | 15.318 µs | -100.000% |
-| deep/10_000 nodes (14-level hierarchy) | - | 75.978 s | 40.315 µs | -100.000% |
-| deep/100_000 nodes (17-level hierarchy) | - | - | 2.7644 ms| - |
-| deep/1_000_000 nodes (20-level hierarchy) | - | - | 1.2130 s| - |
-| deep hierarchy/build | - | 1.4869 µs | 713.45 ns | -4.4346% |
-| deep hierarchy/single | - | 7.1058 µs | 4.6564 µs | -2.0999% |
-| deep hierarchy/relayout | - | 3.7909 µs | 2.1306 µs | -2.4861% |
-| generated benchmarks | - | 256.80 µs | 218.71 µs | -14.485% |
diff --git a/benches/results-2022-12-07.md b/benches/results-2022-12-07.md
new file mode 100644
index 000000000..cec319998
--- /dev/null
+++ b/benches/results-2022-12-07.md
@@ -0,0 +1,32 @@
+# Benchmarks (Taffy 0.2 vs Taffy 0.1 and Yoga)
+
+- Taffy `0.1` results come from commit `52794ddf23dea463fcad5fb73db4f8362b894866`
+- Taffy `0.2` results come from commit `44763a9e74e87423f3158014d6d06c762ce44d19`
+- Run on a 2021 MacBook Pro with M1 Pro processor.
+- Taffy benchmarks are using criterion (10 iterations).
+- Yoga benchmarks run via the `yoga-layout-prebuilt` npm package, they were run a few times manually and it was verified that variance in the numbers of each run was minimal. It should be noted that this is using an old version of Yoga.
+
+| Benchmark | Yoga | Taffy 0.1 | Taffy 0.2 | % change (0.1 -> 0.2) |
+| --- | --- | --- | --- | --- |
+| yoga/10 nodes (1-level hierarchy) | 45.1670 µs | 2.2851 µs | 2.0787 µs | -9.3338% |
+| yoga/100 nodes (2-level hierarchy) | 134.1250 µs | 75.518 µs | 41.022 µs | -46.577% |
+| yoga/1_000 nodes (3-level hierarchy) | 1.2221 ms | 1.7794 ms | 355.50 µs | -79.608% |
+| yoga/10_000 nodes (4-level hierarchy) | 13.8672 ms | 52.117 ms | 3.6848 ms | -92.968% |
+| yoga/100_000 nodes (5-level hierarchy) | 141.5307 ms | 1.5626 s | 39.830 ms | -97.459% |
+| yoga /1_000_000 nodes (6-level hierarchy) | - | - | 384.19 ms | - |
+| wide/10 nodes (2-level hierarchy) | - | 6.1508 µs | 4.1094 µs | -33.923% |
+| wide/100 nodes (2-level hierarchy) | - | 66.602 µs | 41.056 µs | -35.742% |
+| wide/1_000 nodes (2-level hierarchy) | - | 699.18 µs | 445.01 µs | -36.279% |
+| wide/10_000 nodes (2-level hierarchy) | - | 8.8244 ms | 7.1313 ms | -16.352% |
+| wide/100_000 nodes (2-level hierarchy) | - | 204.48 ms | 242.93 ms | +18.803% |
+| semi-wide/100_000 nodes (7-level hierarchy) | - | 2.6539 s | 69.141 ms | -97.402% |
+| deep/4000 nodes (12-level hierarchy)) | - | 5.2320 s | 2.7363 ms | -99.947% |
+| deep/10_000 nodes (14-level hierarchy) | - | 75.207 s | 6.9415 ms | -99.991% |
+| deep/100_000 nodes (17-level hierarchy) | - | - | 102.72 ms| - |
+| deep/1_000_000 nodes (20-level hierarchy) | - | - | 799.35 ms | - |
+| super-deep/100 nodes (100-level hierarchy) | - | - | 111.26 µs | - |
+| super-deep/1000 nodes (1000-level hierarchy) | - | - | 1.1746 ms | - |
+| deep hierarchy/build | - | 1.5060 µs | 616.12 ns | -1.5167% |
+| deep hierarchy/single | - | 7.1453 µs | 4.5461 µs | -0.5156% |
+| deep hierarchy/relayout | - | 3.7863 µs | 2.1275 µs | -1.0900% |
+| generated benchmarks | - | 255.83 µs | 221.73 µs | -13.125% |