Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/benches/wasi.rs
1685 views
1
//! Measure some common WASI call scenarios.
2
3
use criterion::{Criterion, criterion_group, criterion_main};
4
use std::{fs::File, path::Path, time::Instant};
5
use wasmtime::{Engine, Linker, Module, Store, TypedFunc};
6
use wasmtime_wasi::{DirPerms, FilePerms, WasiCtx, p1::WasiP1Ctx};
7
8
criterion_group!(benches, bench_wasi);
9
criterion_main!(benches);
10
11
fn bench_wasi(c: &mut Criterion) {
12
let _ = env_logger::try_init();
13
14
// Build a zero-filled test file if it does not yet exist.
15
let test_file = Path::new("benches/wasi/test.bin");
16
if !test_file.is_file() {
17
let file = File::create(test_file).unwrap();
18
file.set_len(4096).unwrap();
19
}
20
21
// Benchmark each `*.wat` file in the `wasi` directory.
22
for file in std::fs::read_dir("benches/wasi").unwrap() {
23
let path = file.unwrap().path();
24
if path.extension().map(|e| e == "wat").unwrap_or(false) {
25
let wat = std::fs::read(&path).unwrap();
26
let (mut store, run_fn) = instantiate(&wat);
27
let bench_name = format!("wasi/{}", path.file_name().unwrap().to_string_lossy());
28
// To avoid overhead, the module itself must iterate the expected
29
// number of times in a specially-crafted `run` function (see
30
// `instantiate` for details).
31
c.bench_function(&bench_name, move |b| {
32
b.iter_custom(|iters| {
33
let start = Instant::now();
34
let result = run_fn.call(&mut store, iters).unwrap();
35
assert_eq!(iters, result);
36
start.elapsed()
37
})
38
});
39
}
40
}
41
}
42
43
/// Compile and instantiate the Wasm module, returning the exported `run`
44
/// function. This function expects `run` to:
45
/// - have a single `u64` parameter indicating the number of loop iterations to
46
/// execute
47
/// - execute the body of the function for that number of loop iterations
48
/// - return a single `u64` indicating how many loop iterations were executed
49
/// (to double-check)
50
fn instantiate(wat: &[u8]) -> (Store<WasiP1Ctx>, TypedFunc<u64, u64>) {
51
let engine = Engine::default();
52
let wasi = wasi_context();
53
let mut store = Store::new(&engine, wasi);
54
let module = Module::new(&engine, wat).unwrap();
55
let mut linker = Linker::new(&engine);
56
wasmtime_wasi::p1::add_to_linker_sync(&mut linker, |cx| cx).unwrap();
57
let instance = linker.instantiate(&mut store, &module).unwrap();
58
let run = instance.get_typed_func(&mut store, "run").unwrap();
59
(store, run)
60
}
61
62
/// Build a WASI context with some actual data to retrieve.
63
fn wasi_context() -> WasiP1Ctx {
64
WasiCtx::builder()
65
.envs(&[
66
("a".to_string(), "b".to_string()),
67
("b".to_string(), "c".to_string()),
68
("c".to_string(), "d".to_string()),
69
])
70
.args(&[
71
"exe".to_string(),
72
"--flag1".to_string(),
73
"--flag2".to_string(),
74
"--flag3".to_string(),
75
"--flag4".to_string(),
76
])
77
.preopened_dir("benches/wasi", "/", DirPerms::READ, FilePerms::READ)
78
.unwrap()
79
.build_p1()
80
}
81
82