perf: add structured performance profiling for unitig stages

Wraps graph construction, degree computation, and unitig enumeration phases with `Stage` start/stop calls. Intervals are recorded in a `Reporter` instance and printed upon completion to provide granular timing metrics for each computational stage.
This commit is contained in:
Eric Coissac
2026-06-05 08:23:41 +02:00
parent 2f29ee2240
commit 249998beed
+9 -1
View File
@@ -5,7 +5,7 @@ use clap::Args;
use obidebruinj::GraphDeBruijn; use obidebruinj::GraphDeBruijn;
use obifastwrite::write_unitig; use obifastwrite::write_unitig;
use obikindex::KmerIndex; use obikindex::KmerIndex;
use obisys::{progress_bar, spinner}; use obisys::{Reporter, Stage, progress_bar, spinner};
use rayon::prelude::*; use rayon::prelude::*;
use tracing::info; use tracing::info;
@@ -35,9 +35,11 @@ pub fn run(args: UnitigArgs) {
let filters = args.filter.build_filters(&idx.meta().genomes); let filters = args.filter.build_filters(&idx.meta().genomes);
let partition = idx.partition(); let partition = idx.partition();
let mut rep = Reporter::new();
// ── Phase 1 : collect filtered kmers in parallel ────────────────────────── // ── Phase 1 : collect filtered kmers in parallel ──────────────────────────
let pb = progress_bar("unitig", n as u64, "partitions"); let pb = progress_bar("unitig", n as u64, "partitions");
let stage = Stage::start("build graph");
let g = (0..n) let g = (0..n)
.into_par_iter() .into_par_iter()
.fold( .fold(
@@ -57,17 +59,21 @@ pub fn run(args: UnitigArgs) {
) )
.reduce(GraphDeBruijn::new, |mut a, b| { a.merge(b); a }); .reduce(GraphDeBruijn::new, |mut a, b| { a.merge(b); a });
pb.finish_and_clear(); pb.finish_and_clear();
rep.push(stage.stop());
info!("unitig: {} distinct k-mers", g.len()); info!("unitig: {} distinct k-mers", g.len());
// ── Phase 2 : compute degrees (in-memory, no progress needed) ──────────── // ── Phase 2 : compute degrees (in-memory, no progress needed) ────────────
let stage = Stage::start("compute degrees");
g.compute_degrees(); g.compute_degrees();
rep.push(stage.stop());
// ── Phase 3 : enumerate unitigs and write as FASTA ──────────────────────── // ── Phase 3 : enumerate unitigs and write as FASTA ────────────────────────
let pb = spinner("unitig"); let pb = spinner("unitig");
let stdout = io::stdout(); let stdout = io::stdout();
let mut out = BufWriter::new(stdout.lock()); let mut out = BufWriter::new(stdout.lock());
let stage = Stage::start("enumerate unitigs");
for (j, unitig) in g.iter_unitig().enumerate() { for (j, unitig) in g.iter_unitig().enumerate() {
write_unitig(&unitig, k, 0, j, &mut out).unwrap_or_else(|e| { write_unitig(&unitig, k, 0, j, &mut out).unwrap_or_else(|e| {
eprintln!("write error: {e}"); eprintln!("write error: {e}");
@@ -78,6 +84,8 @@ pub fn run(args: UnitigArgs) {
} }
} }
pb.finish_and_clear(); pb.finish_and_clear();
rep.push(stage.stop());
out.flush().expect("flush error"); out.flush().expect("flush error");
rep.print();
} }