Skip to content

Commit 34da136

Browse files
committed
bench: switch to criterion
Switches the benchmark framework to Criterion. The default Rust std test framework has a hardcoded goal execution time of 1ms for each benchmark. This makes it unsuitable for sample-based profiling because the benchmark doesn't run for very long. Adds a utility script to run tests under a profiler.
1 parent 8c52723 commit 34da136

File tree

4 files changed

+79
-51
lines changed

4 files changed

+79
-51
lines changed

benches/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
target
2+
perf.data
3+
perf.data.old
4+
Cargo.lock

benches/Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ edition = "2018"
77
harfbuzz_rs = { git = "https://github.com/harfbuzz/harfbuzz_rs/", rev = "43f0fb5" }
88
rustybuzz = { path = "../" }
99

10+
[dev-dependencies]
11+
criterion = "0.3"
12+
criterion-macro = "0.3"
13+
1014
[features]
1115
default = ["hb"]
1216
hb = []
17+
18+
[profile.bench]
19+
debug = 2

benches/measure.sh

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
export HARFBUZZ_SYS_NO_PKG_CONFIG=""
5+
6+
# Using jq here would be best, however it's not installed by default on many systems, and this isn't a critical script.
7+
TEST_EXECUTABLE=$(
8+
cargo +nightly bench \
9+
--message-format=json \
10+
--no-default-features --no-run | \
11+
sed -n 's/^{"reason":"compiler-artifact".*"executable":"\([^"]*\)".*}$/\1/p'
12+
)
13+
14+
exec perf record --call-graph dwarf -- "$TEST_EXECUTABLE" --bench --profile-time 5 "$@"

benches/src/lib.rs

+54-51
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#![feature(test)]
22
#![allow(dead_code)]
33
#![allow(unused_imports)]
4+
#![feature(custom_test_frameworks)]
5+
#![test_runner(criterion::runner)]
46

57
extern crate test;
68

9+
use criterion::{black_box, Criterion};
10+
use criterion_macro::criterion;
711
use rustybuzz::ttf_parser::Tag;
812

913
struct CustomVariation {
@@ -29,34 +33,34 @@ macro_rules! simple_bench {
2933
use super::*;
3034
use test::Bencher;
3135

32-
#[bench]
33-
fn rb(bencher: &mut Bencher) {
36+
#[criterion]
37+
fn rb(c: &mut Criterion) {
3438
let font_data = std::fs::read($font_path).unwrap();
3539
let text = std::fs::read_to_string($text_path).unwrap().trim().to_string();
36-
bencher.iter(|| {
37-
test::black_box({
38-
let face = rustybuzz::Face::from_slice(&font_data, 0).unwrap();
39-
let mut buffer = rustybuzz::UnicodeBuffer::new();
40-
buffer.push_str(&text);
41-
buffer.reset_clusters();
42-
rustybuzz::shape(&face, &[], buffer);
43-
});
44-
})
45-
}
4640

47-
#[cfg(feature = "hb")]
48-
#[bench]
49-
fn hb(bencher: &mut Bencher) {
50-
let font_data = std::fs::read($font_path).unwrap();
51-
let text = std::fs::read_to_string($text_path).unwrap().trim().to_string();
52-
bencher.iter(|| {
53-
test::black_box({
54-
let face = harfbuzz_rs::Face::from_bytes(&font_data, 0);
55-
let font = harfbuzz_rs::Font::new(face);
41+
c.bench_function(&format!("{}::{}", module_path!(), "rb"), |bencher| {
42+
let face = rustybuzz::Face::from_slice(&font_data, 0).unwrap();
43+
44+
bencher.iter(|| {
45+
black_box({
46+
let mut buffer = rustybuzz::UnicodeBuffer::new();
47+
buffer.push_str(&text);
48+
buffer.reset_clusters();
49+
rustybuzz::shape(&face, &[], buffer);
50+
});
51+
})
52+
});
53+
54+
#[cfg(feature = "hb")]
55+
c.bench_function(&format!("{}::{}", module_path!(), "hb"), |bencher| {
56+
let face = harfbuzz_rs::Face::from_bytes(&font_data, 0);
57+
let font = harfbuzz_rs::Font::new(face);
58+
59+
bencher.iter(|| {
5660
let buffer = harfbuzz_rs::UnicodeBuffer::new().add_str(&text);
57-
harfbuzz_rs::shape(&font, buffer, &[])
58-
});
59-
})
61+
black_box({ harfbuzz_rs::shape(&font, buffer, &[]) });
62+
})
63+
});
6064
}
6165
}
6266
};
@@ -67,36 +71,35 @@ macro_rules! simple_bench {
6771
use super::*;
6872
use test::Bencher;
6973

70-
#[bench]
71-
fn rb(bencher: &mut Bencher) {
72-
let font_data = std::fs::read($font_path).unwrap();
73-
let text = std::fs::read_to_string($text_path).unwrap().trim().to_string();
74-
bencher.iter(|| {
75-
test::black_box({
76-
let mut face = rustybuzz::Face::from_slice(&font_data, 0).unwrap();
77-
face.set_variations($variations);
78-
let mut buffer = rustybuzz::UnicodeBuffer::new();
79-
buffer.push_str(&text);
80-
buffer.reset_clusters();
81-
rustybuzz::shape(&face, &[], buffer);
82-
});
83-
})
84-
}
85-
86-
#[cfg(feature = "hb")]
87-
#[bench]
88-
fn hb(bencher: &mut Bencher) {
74+
#[criterion]
75+
fn rb(c: &mut Criterion) {
8976
let font_data = std::fs::read($font_path).unwrap();
9077
let text = std::fs::read_to_string($text_path).unwrap().trim().to_string();
91-
bencher.iter(|| {
92-
test::black_box({
93-
let face = harfbuzz_rs::Face::from_bytes(&font_data, 0);
94-
let mut font = harfbuzz_rs::Font::new(face);
95-
font.set_variations($variations);
78+
c.bench_function(&format!("{}::{}", module_path!(), "rb"), |bencher| {
79+
let mut face = rustybuzz::Face::from_slice(&font_data, 0).unwrap();
80+
face.set_variations($variations);
81+
82+
bencher.iter(|| {
83+
black_box({
84+
let mut buffer = rustybuzz::UnicodeBuffer::new();
85+
buffer.push_str(&text);
86+
buffer.reset_clusters();
87+
rustybuzz::shape(&face, &[], buffer);
88+
});
89+
})
90+
});
91+
92+
#[cfg(feature = "hb")]
93+
c.bench_function(&format!("{}::{}", module_path!(), "hb"), |bencher| {
94+
let face = harfbuzz_rs::Face::from_bytes(&font_data, 0);
95+
let mut font = harfbuzz_rs::Font::new(face);
96+
font.set_variations($variations);
97+
98+
bencher.iter(|| {
9699
let buffer = harfbuzz_rs::UnicodeBuffer::new().add_str(&text);
97-
harfbuzz_rs::shape(&font, buffer, &[])
98-
});
99-
})
100+
black_box({ harfbuzz_rs::shape(&font, buffer, &[]) });
101+
})
102+
});
100103
}
101104
}
102105
};

0 commit comments

Comments
 (0)