summaryrefslogtreecommitdiff
path: root/benches
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-01-30 01:12:38 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-01-30 01:12:38 +0100
commit893396aa3ce270280a2a1a87007a4b84edc8b898 (patch)
tree59690b8bee97a158a01dd49f4b6e611bdf284546 /benches
parent4919d8c2f86f69f669a1afba2a28d5c344fe7197 (diff)
perf: add more benchmarks
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'benches')
-rw-r--r--benches/argon2id.rs60
-rw-r--r--benches/fibonacci.rs42
-rw-r--r--benches/selfhosted.rs30
-rw-r--r--benches/util/mod.rs10
4 files changed, 137 insertions, 5 deletions
diff --git a/benches/argon2id.rs b/benches/argon2id.rs
new file mode 100644
index 0000000..4504812
--- /dev/null
+++ b/benches/argon2id.rs
@@ -0,0 +1,60 @@
+mod util;
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use util::wasm_to_twasm;
+
+fn run_tinywasm(twasm: &[u8], params: (i32, i32, i32), name: &str) {
+ let (mut store, instance) = util::tinywasm(twasm);
+ let argon2 = instance.exported_func::<(i32, i32, i32), i32>(&store, name).expect("exported_func");
+ argon2.call(&mut store, params).expect("call");
+}
+
+fn run_wasmi(wasm: &[u8], params: (i32, i32, i32), name: &str) {
+ let (module, mut store, linker) = util::wasmi(wasm);
+ let instance = linker.instantiate(&mut store, &module).expect("instantiate").start(&mut store).expect("start");
+ let argon2 = instance.get_typed_func::<(i32, i32, i32), i32>(&mut store, name).expect("get_typed_func");
+ argon2.call(&mut store, params).expect("call");
+}
+
+fn run_wasmer(wasm: &[u8], params: (i32, i32, i32), name: &str) {
+ use wasmer::Value;
+ let (mut store, instance) = util::wasmer(wasm);
+ let argon2 = instance.exports.get_function(name).expect("get_function");
+ argon2.call(&mut store, &[Value::I32(params.0), Value::I32(params.1), Value::I32(params.2)]).expect("call");
+}
+
+fn run_native(params: (i32, i32, i32)) {
+ fn run_native(m_cost: i32, t_cost: i32, p_cost: i32) {
+ let password = b"password";
+ let salt = b"some random salt";
+
+ let params = argon2::Params::new(m_cost as u32, t_cost as u32, p_cost as u32, None).unwrap();
+ let argon = argon2::Argon2::new(argon2::Algorithm::Argon2id, argon2::Version::V0x13, params);
+
+ let mut hash = [0u8; 32];
+ argon.hash_password_into(password, salt, &mut hash).unwrap();
+ }
+ run_native(params.0, params.1, params.2)
+}
+
+const ARGON2ID: &[u8] = include_bytes!("../examples/rust/out/argon2id.wasm");
+fn criterion_benchmark(c: &mut Criterion) {
+ let twasm = wasm_to_twasm(ARGON2ID);
+ let params = (1000, 2, 1);
+
+ let mut group = c.benchmark_group("argon2id");
+ group.measurement_time(std::time::Duration::from_secs(7));
+ group.sample_size(10);
+
+ group.bench_function("native", |b| b.iter(|| run_native(black_box(params))));
+ group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm, black_box(params), "argon2id")));
+ group.bench_function("wasmi", |b| b.iter(|| run_wasmi(&ARGON2ID, black_box(params), "argon2id")));
+ group.bench_function("wasmer", |b| b.iter(|| run_wasmer(&ARGON2ID, black_box(params), "argon2id")));
+}
+
+criterion_group!(
+ name = benches;
+ config = Criterion::default().significance_level(0.1);
+ targets = criterion_benchmark
+);
+
+criterion_main!(benches);
diff --git a/benches/fibonacci.rs b/benches/fibonacci.rs
index ca83869..1d1134a 100644
--- a/benches/fibonacci.rs
+++ b/benches/fibonacci.rs
@@ -4,15 +4,45 @@ use util::wasm_to_twasm;
fn run_tinywasm(twasm: &[u8], iterations: i32, name: &str) {
let (mut store, instance) = util::tinywasm(twasm);
- let hello = instance.exported_func::<i32, i32>(&store, name).expect("exported_func");
- hello.call(&mut store, iterations).expect("call");
+ let fib = instance.exported_func::<i32, i32>(&store, name).expect("exported_func");
+ fib.call(&mut store, iterations).expect("call");
}
fn run_wasmi(wasm: &[u8], iterations: i32, name: &str) {
let (module, mut store, linker) = util::wasmi(wasm);
let instance = linker.instantiate(&mut store, &module).expect("instantiate").start(&mut store).expect("start");
- let hello = instance.get_typed_func::<i32, i32>(&mut store, name).expect("get_typed_func");
- hello.call(&mut store, iterations).expect("call");
+ let fib = instance.get_typed_func::<i32, i32>(&mut store, name).expect("get_typed_func");
+ fib.call(&mut store, iterations).expect("call");
+}
+
+fn run_wasmer(wasm: &[u8], iterations: i32, name: &str) {
+ use wasmer::*;
+ let engine: Engine = wasmer::Singlepass::default().into();
+ let mut store = Store::default();
+ let import_object = imports! {};
+ let module = wasmer::Module::from_binary(&engine, &wasm).expect("wasmer::Module::from_binary");
+ let instance = Instance::new(&mut store, &module, &import_object).expect("Instance::new");
+ let fib = instance.exports.get_typed_function::<i32, i32>(&mut store, name).expect("get_function");
+ fib.call(&mut store, iterations).expect("call");
+}
+
+fn run_native(n: i32) -> i32 {
+ let mut sum = 0;
+ let mut last = 0;
+ let mut curr = 1;
+ for _i in 1..n {
+ sum = last + curr;
+ last = curr;
+ curr = sum;
+ }
+ sum
+}
+
+fn run_native_recursive(n: i32) -> i32 {
+ if n <= 1 {
+ return n;
+ }
+ run_native_recursive(n - 1) + run_native_recursive(n - 2)
}
const FIBONACCI: &[u8] = include_bytes!("../examples/rust/out/fibonacci.wasm");
@@ -21,15 +51,19 @@ fn criterion_benchmark(c: &mut Criterion) {
{
let mut group = c.benchmark_group("fibonacci");
+ group.bench_function("native", |b| b.iter(|| run_native(black_box(60))));
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm, black_box(60), "fibonacci")));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(&FIBONACCI, black_box(60), "fibonacci")));
+ group.bench_function("wasmer", |b| b.iter(|| run_wasmer(&FIBONACCI, black_box(60), "fibonacci")));
}
{
let mut group = c.benchmark_group("fibonacci-recursive");
group.measurement_time(std::time::Duration::from_secs(5));
+ group.bench_function("native", |b| b.iter(|| run_native_recursive(black_box(26))));
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm, black_box(26), "fibonacci_recursive")));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(&FIBONACCI, black_box(26), "fibonacci_recursive")));
+ group.bench_function("wasmer", |b| b.iter(|| run_wasmer(&FIBONACCI, black_box(26), "fibonacci_recursive")));
}
}
diff --git a/benches/selfhosted.rs b/benches/selfhosted.rs
index 4464579..57146e7 100644
--- a/benches/selfhosted.rs
+++ b/benches/selfhosted.rs
@@ -3,6 +3,17 @@ use criterion::{criterion_group, criterion_main, Criterion};
use crate::util::twasm_to_module;
+fn run_native() {
+ use tinywasm::*;
+ let module = tinywasm::Module::parse_bytes(include_bytes!("../examples/rust/out/print.wasm")).expect("parse");
+ let mut store = Store::default();
+ let mut imports = Imports::default();
+ imports.define("env", "printi32", Extern::typed_func(|_: FuncContext<'_>, _: i32| Ok(()))).expect("define");
+ let instance = ModuleInstance::instantiate(&mut store, module, Some(imports)).expect("instantiate");
+ let hello = instance.exported_func::<(i32, i32), ()>(&store, "add_and_print").expect("exported_func");
+ hello.call(&mut store, (2, 3)).expect("call");
+}
+
fn run_tinywasm(twasm: &[u8]) {
use tinywasm::*;
let module = twasm_to_module(twasm);
@@ -26,18 +37,35 @@ fn run_wasmi(wasm: &[u8]) {
hello.call(&mut store, ()).expect("call");
}
+fn run_wasmer(wasm: &[u8]) {
+ use wasmer::*;
+ let engine = wasmer::Engine::default();
+ let mut store = Store::default();
+ let import_object = imports! {
+ "env" => {
+ "printi32" => Function::new_typed(&mut store, |_: i32| {}),
+ },
+ };
+ let module = wasmer::Module::from_binary(&engine, &wasm).expect("wasmer::Module::from_binary");
+ let instance = Instance::new(&mut store, &module, &import_object).expect("Instance::new");
+ let hello = instance.exports.get_function("hello").expect("get_function");
+ hello.call(&mut store, &[]).expect("call");
+}
+
const TINYWASM: &[u8] = include_bytes!("../examples/rust/out/tinywasm.wasm");
fn criterion_benchmark(c: &mut Criterion) {
let twasm = util::wasm_to_twasm(TINYWASM);
let mut group = c.benchmark_group("selfhosted");
+ group.bench_function("native", |b| b.iter(|| run_native()));
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm)));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
+ group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
}
criterion_group!(
name = benches;
- config = Criterion::default().sample_size(500).measurement_time(std::time::Duration::from_secs(5)).significance_level(0.1);
+ config = Criterion::default().sample_size(100).measurement_time(std::time::Duration::from_secs(5)).significance_level(0.1);
targets = criterion_benchmark
);
diff --git a/benches/util/mod.rs b/benches/util/mod.rs
index 69510a5..aa7b418 100644
--- a/benches/util/mod.rs
+++ b/benches/util/mod.rs
@@ -30,3 +30,13 @@ pub fn wasmi(wasm: &[u8]) -> (wasmi::Module, wasmi::Store<()>, wasmi::Linker<()>
let linker = <Linker<()>>::new(&engine);
(module, store, linker)
}
+
+pub fn wasmer(wasm: &[u8]) -> (wasmer::Store, wasmer::Instance) {
+ use wasmer::*;
+ let engine: Engine = wasmer::Singlepass::default().into();
+ let mut store = Store::default();
+ let import_object = imports! {};
+ let module = wasmer::Module::from_binary(&engine, &wasm).expect("wasmer::Module::from_binary");
+ let instance = Instance::new(&mut store, &module, &import_object).expect("Instance::new");
+ (store, instance)
+}