all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH v2 pxar 1/2] Add `compare-read.rs` to examples and drop feature `async-examples`
@ 2023-07-31 13:34 Max Carrara
  2023-07-31 13:34 ` [pbs-devel] [PATCH v2 pxar 2/2] decoder: aio: improve performance of async file reads Max Carrara
  2023-07-31 14:58 ` [pbs-devel] [PATCH v2 pxar 1/2] Add `compare-read.rs` to examples and drop feature `async-examples` Fabian Grünbichler
  0 siblings, 2 replies; 6+ messages in thread
From: Max Carrara @ 2023-07-31 13:34 UTC (permalink / raw)
  To: pbs-devel

`compare-read.rs` may be used to compare read speeds between pxar
accessors and decoders, both synchronous and asynchronous versions.

The `async-examples` feature is dropped in favour of declaring
`[dev-dependencies]` in `Cargo.toml`.

Signed-off-by: Max Carrara <m.carrara@proxmox.com>
---
 Changes v1 --> v2:
  * Remove addition of `tokio/io-util` as dependency
  * Add example `compare-read`
  * Remove feature `async-example` in favour of `[dev-dependencies]`

 Cargo.toml               |  20 +++---
 examples/compare-read.rs | 150 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+), 8 deletions(-)
 create mode 100644 examples/compare-read.rs

diff --git a/Cargo.toml b/Cargo.toml
index d120e70..8669e30 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,10 @@ exclude = [
 [[example]]
 name = "apxar"
 path = "examples/apxar.rs"
-required-features = [ "async-example" ]
+
+[[example]]
+name = "compare-read"
+path = "examples/compare-read.rs"

 [[example]]
 name = "pxarcmd"
@@ -47,6 +50,14 @@ siphasher = "0.3"

 tokio = { version = "1.0", optional = true, default-features = false }

+[dev-dependencies]
+anyhow = "1.0"
+tokio = { version = "1.0", default-features = false, features = [
+    "fs",
+    "macros",
+    "rt-multi-thread"
+] }
+
 [target.'cfg(target_os = "linux")'.dependencies]
 libc = "0.2"

@@ -57,11 +68,4 @@ tokio-fs = [ "tokio-io", "tokio/fs" ]

 full = [ "tokio-fs"]

-async-example = [
-    "tokio-io",
-    "tokio-fs",
-    "tokio/rt-multi-thread",
-    "tokio/macros",
-]
-
 test-harness = []
diff --git a/examples/compare-read.rs b/examples/compare-read.rs
new file mode 100644
index 0000000..c908077
--- /dev/null
+++ b/examples/compare-read.rs
@@ -0,0 +1,150 @@
+//! # Compare Read Speeds of Accessors and Decoders
+//!
+//! This example is used to compare read speeds between:
+//!
+//! * [`aio::Accessor`][pxar::accessor::aio::Accessor]
+//! * [`sync::Accessor`][pxar::accessor::sync::Accessor]
+//! * [`aio::Decoder`][pxar::decoder::aio::Decoder]
+//! * [`sync::Decoder`][pxar::decoder::sync::Decoder]
+//!
+//! ## Usage
+//!
+//! You may run this example directly on a PXAR archive:
+//!
+//! ```bash
+//! cargo run -q --example compare-read [FILE_PATH]
+//! cargo run -q --release --example compare-read [FILE_PATH]
+//! ```
+
+use std::ffi::OsStr;
+use std::future::Future;
+use std::time::Duration;
+
+use anyhow::{Context, Result};
+use pxar::accessor::aio::Accessor as AioAccessor;
+use pxar::accessor::sync::Accessor as SyncAccessor;
+use pxar::decoder::aio::Decoder as AioDecoder;
+use pxar::decoder::sync::Decoder as SyncDecoder;
+
+async fn read_with_decoder(file: &OsStr) -> Result<()> {
+    let file = tokio::fs::File::open(file)
+        .await
+        .context("failed to open file")?;
+
+    let mut reader = AioDecoder::from_tokio(file)
+        .await
+        .context("failed to open pxar archive contents")?;
+
+    let mut entries = vec![];
+
+    while let Some(entry) = reader.next().await {
+        let entry = entry.context("failed to parse entry")?;
+
+        entries.push(entry);
+    }
+
+    Ok(())
+}
+
+async fn read_with_decoder_sync(file: &OsStr) -> Result<()> {
+    let file = std::fs::File::open(file).context("failed to open file")?;
+
+    let reader = SyncDecoder::from_std(file).context("failed to open pxar archive contents")?;
+
+    let mut entries = vec![];
+
+    for entry in reader {
+        let entry = entry.context("failed to parse entry")?;
+        entries.push(entry);
+    }
+
+    Ok(())
+}
+
+async fn read_with_accessor(file: &OsStr) -> Result<()> {
+    let accessor = AioAccessor::open(file)
+        .await
+        .context("failed to open pxar archive contents")?;
+
+    let dir = accessor.open_root_ref().await?;
+    let mut decode_full = dir.decode_full().await?;
+
+    let mut entries = vec![];
+
+    while let Some(entry) = decode_full.next().await {
+        let entry = entry.context("failed to parse entry")?;
+
+        entries.push(entry);
+    }
+
+    Ok(())
+}
+
+async fn read_with_accessor_sync(file: &OsStr) -> Result<()> {
+    let accessor = SyncAccessor::open(file).context("failed to open pxar archive contents")?;
+
+    let dir = accessor.open_root_ref()?;
+    let decode_full = dir.decode_full()?;
+
+    let mut entries = vec![];
+
+    for entry in decode_full {
+        let entry = entry.context("failed to parse entry")?;
+
+        entries.push(entry);
+    }
+
+    Ok(())
+}
+
+async fn measure_duration<F, R>(future: F) -> (R, Duration)
+where
+    F: Future<Output = R>,
+    R: Send + 'static,
+{
+    use std::time::Instant;
+    let start = Instant::now();
+    let return_value = future.await;
+    let elapsed = start.elapsed();
+
+    (return_value, elapsed)
+}
+
+async fn run_reads(file: &OsStr) -> Result<()> {
+    let (result, elapsed) = measure_duration(read_with_decoder(&file)).await;
+    println!("With aio::Decoder:   {result:?} (elapsed: {elapsed:#?})");
+
+    let (result, elapsed) = measure_duration(read_with_decoder_sync(&file)).await;
+    println!("With sync::Decoder:  {result:?} (elapsed: {elapsed:#?})");
+
+    let (result, elapsed) = measure_duration(read_with_accessor(&file)).await;
+    println!("With aio::Accessor:  {result:?} (elapsed: {elapsed:#?})");
+
+    let (result, elapsed) = measure_duration(read_with_accessor_sync(&file)).await;
+    println!("With sync::Accessor: {result:?} (elapsed: {elapsed:#?})");
+
+    Ok(())
+}
+
+#[tokio::main]
+async fn main() -> Result<()> {
+    let mode = if cfg!(debug_assertions) {
+        "debug"
+    } else {
+        "release"
+    };
+
+    println!("PXAR Read Performance Comparison");
+    println!("Running in mode: {mode}\n");
+
+    let mut args = std::env::args_os().skip(1);
+
+    let file = args.next().context("expected file name")?;
+    println!("First pass:");
+    run_reads(&file).await?;
+
+    println!("\nSecond pass:");
+    run_reads(&file).await?;
+
+    Ok(())
+}
--
2.39.2





^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-08-04 11:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-31 13:34 [pbs-devel] [PATCH v2 pxar 1/2] Add `compare-read.rs` to examples and drop feature `async-examples` Max Carrara
2023-07-31 13:34 ` [pbs-devel] [PATCH v2 pxar 2/2] decoder: aio: improve performance of async file reads Max Carrara
2023-07-31 14:57   ` Fabian Grünbichler
2023-07-31 15:14     ` Max Carrara
2023-08-04 11:32   ` Wolfgang Bumiller
2023-07-31 14:58 ` [pbs-devel] [PATCH v2 pxar 1/2] Add `compare-read.rs` to examples and drop feature `async-examples` Fabian Grünbichler

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal