use criterion::{criterion_group, criterion_main, Criterion, Throughput};
use fsys::{builder, Method};
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use tokio::runtime::Runtime;
static C: AtomicU64 = AtomicU64::new(0);
fn tmp_path(tag: &str) -> PathBuf {
let n = C.fetch_add(1, Ordering::Relaxed);
std::env::temp_dir().join(format!(
"fsys_bench_native_vs_blocking_{}_{}_{}.dat",
std::process::id(),
n,
tag
))
}
fn build_runtime() -> Runtime {
tokio::runtime::Builder::new_multi_thread()
.worker_threads(2)
.enable_all()
.build()
.expect("tokio runtime")
}
fn bench_async_blocking_write_4k(c: &mut Criterion) {
let rt = build_runtime();
let prior = std::env::var_os("FSYS_DISABLE_NATIVE_ASYNC");
unsafe {
std::env::set_var("FSYS_DISABLE_NATIVE_ASYNC", "1");
}
let fs = Arc::new(builder().method(Method::Direct).build().expect("handle"));
let payload = vec![0xA5u8; 4096];
let mut group = c.benchmark_group("async_blocking_write_4k");
group.throughput(Throughput::Bytes(payload.len() as u64));
group.bench_function("write_async_blocking_path", |b| {
b.iter(|| {
let path = tmp_path("blocking");
let fs = fs.clone();
let payload = payload.clone();
rt.block_on(async move {
let _ = fs.write_async(&path, payload).await;
let _ = std::fs::remove_file(&path);
});
});
});
group.finish();
unsafe {
match prior {
Some(v) => std::env::set_var("FSYS_DISABLE_NATIVE_ASYNC", v),
None => std::env::remove_var("FSYS_DISABLE_NATIVE_ASYNC"),
}
}
}
#[cfg(target_os = "linux")]
fn bench_async_native_write_4k(c: &mut Criterion) {
let rt = build_runtime();
let fs = Arc::new(builder().method(Method::Direct).build().expect("handle"));
{
let fs = fs.clone();
let warmup_path = tmp_path("native_warmup");
rt.block_on(async move {
let _ = fs.write_async(&warmup_path, vec![0u8; 4096]).await;
let _ = std::fs::remove_file(&warmup_path);
});
}
let payload = vec![0xC3u8; 4096];
let mut group = c.benchmark_group("async_native_write_4k");
group.throughput(Throughput::Bytes(payload.len() as u64));
group.bench_function("write_async_native_path", |b| {
b.iter(|| {
let path = tmp_path("native");
let fs = fs.clone();
let payload = payload.clone();
rt.block_on(async move {
let _ = fs.write_async(&path, payload).await;
let _ = std::fs::remove_file(&path);
});
});
});
group.finish();
}
#[cfg(not(target_os = "linux"))]
fn bench_async_native_write_4k(_c: &mut Criterion) {
}
criterion_group!(
benches,
bench_async_blocking_write_4k,
bench_async_native_write_4k
);
criterion_main!(benches);