From 0ac4d859b4508260f15dc10975b73b7e72e972d7 Mon Sep 17 00:00:00 2001 From: MrCroxx Date: Fri, 14 Feb 2025 14:05:40 +0800 Subject: [PATCH 1/2] bench: add tokio spawn_block + std fs benchmark Signed-off-by: MrCroxx --- compio/benches/fs.rs | 152 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/compio/benches/fs.rs b/compio/benches/fs.rs index 30e0797e..592bd5e1 100644 --- a/compio/benches/fs.rs +++ b/compio/benches/fs.rs @@ -2,6 +2,7 @@ use std::{ hint::black_box, io::{Read, Seek, SeekFrom, Write}, path::Path, + sync::Arc, time::Instant, }; @@ -64,6 +65,41 @@ fn read_tokio(b: &mut Bencher, (path, offsets): &(&Path, &[u64])) { }) } +fn read_tokio_std(b: &mut Bencher, (path, offsets): &(&Path, &[u64])) { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + b.to_async(&runtime).iter_custom(|iter| async move { + let file = Arc::new(std::fs::File::open(path).unwrap()); + + let start = Instant::now(); + for _i in 0..iter { + let mut buffer = [0u8; BUFFER_SIZE]; + for &offset in *offsets { + let file = file.clone(); + buffer = tokio::task::spawn_blocking(move || { + #[cfg(windows)] + { + use std::os::windows::fs::FileExt; + file.seek_read(&mut buffer, offset).unwrap(); + } + #[cfg(unix)] + { + use std::os::unix::fs::FileExt; + file.read_at(&mut buffer, offset).unwrap(); + } + buffer + }) + .await + .unwrap(); + } + black_box(buffer); + } + start.elapsed() + }) +} + fn read_compio(b: &mut Bencher, (path, offsets): &(&Path, &[u64])) { let runtime = compio::runtime::Runtime::new().unwrap(); b.to_async(&runtime).iter_custom(|iter| async move { @@ -160,6 +196,34 @@ fn read_all_tokio(b: &mut Bencher, (path, len): &(&Path, u64)) { }) } +fn read_all_tokio_std(b: &mut Bencher, (path, len): &(&Path, u64)) { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + b.to_async(&runtime).iter_custom(|iter| async move { + let mut buffer = [0u8; BUFFER_SIZE]; + + let start = Instant::now(); + for _i in 0..iter { + let mut file = std::fs::File::open(path).unwrap(); + let len = *len; + buffer = tokio::task::spawn_blocking(move || { + let mut read_len = 0; + file.seek(SeekFrom::Start(0)).unwrap(); + while read_len < len { + let read = file.read(&mut buffer).unwrap(); + read_len += read as u64; + } + buffer + }) + .await + .unwrap(); + } + start.elapsed() + }) +} + fn read_all_compio(b: &mut Bencher, (path, len): &(&Path, u64)) { let runtime = compio::runtime::Runtime::new().unwrap(); b.to_async(&runtime).iter_custom(|iter| async move { @@ -223,6 +287,11 @@ fn read(c: &mut Criterion) { group.bench_with_input::<_, _, (&Path, &[u64])>("std", &(&path, &offsets), read_std); group.bench_with_input::<_, _, (&Path, &[u64])>("tokio", &(&path, &offsets), read_tokio); + group.bench_with_input::<_, _, (&Path, &[u64])>( + "tokio_std", + &(&path, &offsets), + read_tokio_std, + ); group.bench_with_input::<_, _, (&Path, &[u64])>("compio", &(&path, &offsets), read_compio); group.bench_with_input::<_, _, (&Path, &[u64])>( "compio-join", @@ -239,6 +308,11 @@ fn read(c: &mut Criterion) { group.bench_with_input::<_, _, (&Path, u64)>("std", &(&path, FILE_SIZE), read_all_std); group.bench_with_input::<_, _, (&Path, u64)>("tokio", &(&path, FILE_SIZE), read_all_tokio); + group.bench_with_input::<_, _, (&Path, u64)>( + "tokio_std", + &(&path, FILE_SIZE), + read_all_tokio_std, + ); group.bench_with_input::<_, _, (&Path, u64)>("compio", &(&path, FILE_SIZE), read_all_compio); #[cfg(target_os = "linux")] group.bench_with_input::<_, _, (&Path, u64)>("monoio", &(&path, FILE_SIZE), read_all_monoio); @@ -287,6 +361,43 @@ fn write_tokio(b: &mut Bencher, (path, offsets, content): &(&Path, &[u64], &[u8] }) } +fn write_tokio_std(b: &mut Bencher, (path, offsets, content): &(&Path, &[u64], &[u8])) { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + b.to_async(&runtime).iter_custom(|iter| async move { + let file = Arc::new(std::fs::OpenOptions::new().write(true).open(path).unwrap()); + let offsets = Arc::new(offsets.to_vec()); + let content = Arc::new(content.to_vec()); + + let start = Instant::now(); + for _i in 0..iter { + let file = file.clone(); + let offsets = offsets.clone(); + let content = content.clone(); + + tokio::task::spawn_blocking(move || { + for offset in offsets.iter() { + #[cfg(windows)] + { + use std::os::windows::fs::FileExt; + file.seek_write(content, offset).unwrap(); + } + #[cfg(unix)] + { + use std::os::unix::fs::FileExt; + file.write_at(&content, *offset).unwrap(); + } + } + }) + .await + .unwrap(); + } + start.elapsed() + }) +} + fn write_compio(b: &mut Bencher, (path, offsets, content): &(&Path, &[u64], &[u8])) { let runtime = compio::runtime::Runtime::new().unwrap(); let content = content.to_vec(); @@ -443,6 +554,37 @@ fn write_all_tokio(b: &mut Bencher, (path, content): &(&Path, &[u8])) { }) } +fn write_all_tokio_std(b: &mut Bencher, (path, content): &(&Path, &[u8])) { + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + b.to_async(&runtime).iter_custom(|iter| async move { + let content = Arc::new(content.to_vec()); + let mut file = std::fs::File::create(path).unwrap(); + + let start = Instant::now(); + for _i in 0..iter { + let content = content.clone(); + file = tokio::task::spawn_blocking(move || { + file.seek(SeekFrom::Start(0)).unwrap(); + let mut write_len = 0; + let total_len = content.len(); + while write_len < total_len { + let write = file + .write(&content[write_len..(write_len + BUFFER_SIZE).min(total_len)]) + .unwrap(); + write_len += write; + } + file + }) + .await + .unwrap(); + } + start.elapsed() + }) +} + fn write_all_compio(b: &mut Bencher, (path, content): &(&Path, &[u8])) { let runtime = compio::runtime::Runtime::new().unwrap(); let content = content.to_vec(); @@ -551,6 +693,11 @@ fn write(c: &mut Criterion) { &(&path, &offsets, &single_content), write_tokio, ); + group.bench_with_input::<_, _, (&Path, &[u64], &[u8])>( + "tokio_std", + &(&path, &offsets, &single_content), + write_tokio_std, + ); group.bench_with_input::<_, _, (&Path, &[u64], &[u8])>( "compio", &(&path, &offsets, &single_content), @@ -581,6 +728,11 @@ fn write(c: &mut Criterion) { group.bench_with_input::<_, _, (&Path, &[u8])>("std", &(&path, &content), write_all_std); group.bench_with_input::<_, _, (&Path, &[u8])>("tokio", &(&path, &content), write_all_tokio); + group.bench_with_input::<_, _, (&Path, &[u8])>( + "tokio_std", + &(&path, &content), + write_all_tokio_std, + ); group.bench_with_input::<_, _, (&Path, &[u8])>("compio", &(&path, &content), write_all_compio); #[cfg(target_os = "linux")] group.bench_with_input::<_, _, (&Path, &[u8])>("monoio", &(&path, &content), write_all_monoio); From 7d4db5ae163273fdefb5d510fad3be87c8c530bb Mon Sep 17 00:00:00 2001 From: MrCroxx Date: Mon, 17 Feb 2025 14:10:21 +0800 Subject: [PATCH 2/2] chore: fix build on windows Signed-off-by: MrCroxx --- compio/benches/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compio/benches/fs.rs b/compio/benches/fs.rs index 592bd5e1..1575f778 100644 --- a/compio/benches/fs.rs +++ b/compio/benches/fs.rs @@ -382,7 +382,7 @@ fn write_tokio_std(b: &mut Bencher, (path, offsets, content): &(&Path, &[u64], & #[cfg(windows)] { use std::os::windows::fs::FileExt; - file.seek_write(content, offset).unwrap(); + file.seek_write(&content, *offset).unwrap(); } #[cfg(unix)] {