[pbs-devel] [PATCH v2 pxar 1/2] Add `compare-read.rs` to examples and drop feature `async-examples`

Fabian Grünbichler f.gruenbichler at proxmox.com
Mon Jul 31 16:58:07 CEST 2023


On July 31, 2023 3:34 pm, Max Carrara wrote:
> `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 at proxmox.com>
> ---

just a note for when this gets applied - both patches obviously change
d/control, so that needs a follow-up commit with the updated version

>  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
> 
> 
> 
> _______________________________________________
> pbs-devel mailing list
> pbs-devel at lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
> 
> 
> 





More information about the pbs-devel mailing list