fastx-io 0.3.0

Fast, streaming FASTA/FASTQ reader and writer for bioinformatics pipelines
Documentation
//! Compute statistics using every core.
//!
//! ```text
//! cargo run --release --features parallel --example parallel_stats -- reads.fq 8
//! ```
//!
//! For an uncompressed file this splits it into byte ranges and parses them in
//! parallel; for a gzipped file that is impossible, so it falls back to parsing
//! on one thread and folding the records in parallel.

#[cfg(not(feature = "parallel"))]
fn main() {
    eprintln!("rebuild with `--features parallel` to run this example");
    std::process::exit(2);
}

#[cfg(feature = "parallel")]
fn main() -> Result<(), fastx::Error> {
    use fastx::parallel;

    let mut args = std::env::args().skip(1);
    let path = match args.next() {
        Some(path) => path,
        None => {
            eprintln!("usage: parallel_stats <FILE> [CHUNKS]");
            std::process::exit(2);
        }
    };
    let chunks: usize = args
        .next()
        .and_then(|n| n.parse().ok())
        .unwrap_or_else(|| std::thread::available_parallelism().map_or(4, |n| n.get()));

    let started = std::time::Instant::now();
    let compressed = fastx::Compression::from_path(&path) != fastx::Compression::None;

    let stats = if compressed {
        parallel::par_stats(&mut fastx::open(&path)?, parallel::DEFAULT_CHUNK_SIZE)?
    } else {
        parallel::par_stats_file(&path, chunks)?
    };

    println!("{stats}");
    eprintln!(
        "{} in {:.2?} using {}",
        path,
        started.elapsed(),
        if compressed {
            "1 parser thread + parallel folding".to_string()
        } else {
            format!("{chunks} parser threads")
        }
    );
    Ok(())
}