wasm_bench_runtime 0.1.0

benchmarker for in browser wasm
Documentation
use std::hint::black_box;
use std::time::Duration;

fn create_output(msg: &str, i: u32) {
    let window = web_sys::window().unwrap();
    let document = window.document().unwrap();

    let result = document.create_element("div").unwrap();
    result
        .set_attribute("id", &format!("wasm_bench_result_{i}"))
        .unwrap();
    result.set_text_content(Some(msg));

    let body = document.body().unwrap();
    body.append_child(&result).unwrap();
}
fn mark_finished() {
    let window = web_sys::window().unwrap();
    let document = window.document().unwrap();

    let result = document.create_element("div").unwrap();
    result.set_attribute("id", "wasm_bench_done").unwrap();

    let body = document.body().unwrap();
    body.append_child(&result).unwrap();
}

#[derive(Default)]
pub struct Bencher {
    index: u32,
}

impl Bencher {
    pub fn start<R: Future<Output = ()> + 'static>(inner: impl FnOnce(Self) -> R) {
        wasm_bindgen_futures::spawn_local(inner(Self { index: 0 }));
    }

    pub async fn bench<A: Clone, R>(&mut self, name: &str, arg: A, func: impl Fn(A) -> R) {
        let performance = web_sys::window().unwrap().performance().unwrap();

        let start = performance.now();
        let _ = func(black_box(arg.clone()));
        let mut end = performance.now();

        if start == end {
            end += 1.0;
        }
        let target_iterations = 5000.0_f64.div_euclid(end - start) as u128;

        let mut total_ms = 0.0;
        for _ in 0..target_iterations {
            let start = performance.now();
            let _ = func(black_box(arg.clone()));
            let end = performance.now();
            total_ms += end - start;
        }
        let average = total_ms / target_iterations as f64;

        create_output(
            &format!("{name} (iters: {target_iterations}): {average:.8}ms"),
            self.index,
        );
        self.index += 1;
        gloo::timers::future::sleep(Duration::from_millis(10)).await;
    }
}

impl Drop for Bencher {
    fn drop(&mut self) {
        mark_finished();
    }
}