1 //! Measure the compilation time of files in `benches/compile`.
2 //!
3 //! Drop in new `*.wasm` or `*.wat` files in `benches/compile` to add
4 //! benchmarks. To try new compilation configurations, modify [`Scenario`].
5
6 use core::fmt;
7 use criterion::measurement::WallTime;
8 use criterion::{BenchmarkGroup, BenchmarkId, Criterion, criterion_group, criterion_main};
9 use std::path::Path;
10 use wasmtime::*;
11
12 /// A compilation configuration, for benchmarking.
13 #[derive(Clone, Copy, Debug)]
14 struct Scenario {
15 compiler: Strategy,
16 opt_level: Option<OptLevel>,
17 }
18
19 impl fmt::Display for Scenario {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 let compiler = match self.compiler {
22 Strategy::Auto => "auto",
23 Strategy::Cranelift => "cranelift",
24 Strategy::Winch => "winch",
25 _ => unreachable!(),
26 };
27 let opt_level = match self.opt_level {
28 Some(OptLevel::None) => "none",
29 Some(OptLevel::Speed) => "speed",
30 Some(OptLevel::SpeedAndSize) => "speed_and_size",
31 None => "none",
32 _ => unreachable!(),
33 };
34 write!(f, "[{compiler}:{opt_level}]")
35 }
36 }
37
38 impl Scenario {
new(compiler: Strategy, opt_level: Option<OptLevel>) -> Self39 fn new(compiler: Strategy, opt_level: Option<OptLevel>) -> Self {
40 Scenario {
41 compiler,
42 opt_level,
43 }
44 }
45
list() -> Vec<Self>46 fn list() -> Vec<Self> {
47 vec![
48 Scenario::new(Strategy::Cranelift, Some(OptLevel::None)),
49 Scenario::new(Strategy::Cranelift, Some(OptLevel::Speed)),
50 Scenario::new(Strategy::Cranelift, Some(OptLevel::SpeedAndSize)),
51 Scenario::new(Strategy::Winch, None),
52 ]
53 }
54
to_config(&self) -> Config55 fn to_config(&self) -> Config {
56 let mut config = Config::default();
57 config.strategy(self.compiler);
58 if let Some(opt_level) = self.opt_level {
59 config.cranelift_opt_level(opt_level);
60 }
61 config
62 }
63 }
64
compile(group: &mut BenchmarkGroup<WallTime>, path: &Path, scenario: Scenario)65 fn compile(group: &mut BenchmarkGroup<WallTime>, path: &Path, scenario: Scenario) {
66 let filename = path.file_name().unwrap().to_str().unwrap();
67 let id = BenchmarkId::new("compile", filename);
68 let bytes = std::fs::read(path).expect("failed to read file");
69 let config = scenario.to_config();
70 let engine = Engine::new(&config).expect("failed to create engine");
71 group.bench_function(id, |b| {
72 b.iter(|| Module::new(&engine, &bytes).unwrap());
73 });
74 }
75
bench_compile(c: &mut Criterion)76 fn bench_compile(c: &mut Criterion) {
77 for scenario in Scenario::list() {
78 let mut group = c.benchmark_group(scenario.to_string());
79 for file in std::fs::read_dir("benches/compile").unwrap() {
80 let path = file.unwrap().path();
81 let extension = path.extension().and_then(|s| s.to_str());
82 if path.is_file() && matches!(extension, Some("wasm") | Some("wat")) {
83 compile(&mut group, &path, scenario);
84 }
85 }
86 group.finish();
87 }
88 }
89
90 criterion_group!(benches, bench_compile);
91 criterion_main!(benches);
92