Benchmarks¶
Benchmarks are useful only when they are reproducible and tied to parity. The repository benchmark suite is designed to report speed while keeping command coverage and Picard-compatible behavior visible.
The current saved suite is already strong enough to support a plain-language
claim: for the commands turbo-picard has accelerated and parity-checked, it
is materially faster than Picard across the board, with a 6.86x slowest
saved speedup, 24.94x geometric mean speedup, and 94.36x top speedup.
The companion MarkDuplicates performance run is also a useful reminder that
“more scalable” is not marketing filler here; it cut median RSS from about
1.2 GB in Picard 3.4.0 to about 8.7 MB on the checked fixture.
For evaluators comparing nearby tools, the saved riker overlap smoke evidence
also supports the practical first-choice story: on the checked WGS bundle and
WGS-only smoke profiles, turbo-picard is 2.14x and 2.10x faster than
riker respectively. Those are small-input overlap checks; for WGS-scale
selection, rerun the comparison on your own representative BAMs with the same
versions and machine profile.
Run the suite¶
python3 tools/bench_suite.py --repeats 1 --skip-build
To refresh the static benchmark assets used by the project site:
printf 'benchmark_date=%s source=python3 tools/bench_suite.py --repeats 1 --skip-build\n' "$(date +%F)" > docs/site/assets/bench-suite-output.txt
python3 tools/bench_suite.py --repeats 1 --skip-build | tee -a docs/site/assets/bench-suite-output.txt
python3 tools/render_benchmark_assets.py --suite-output docs/site/assets/bench-suite-output.txt
python3 tools/verify_benchmark_log_evidence.py
python3 tools/verify_benchmark_suite_coverage.py
python3 tools/verify_benchmark_thresholds.py
The threshold verifier is deliberately simple. Public release evidence must
keep every saved benchmark at parity, keep the slowest saved speedup at or
above 5.00x, keep the geometric mean at or above 20.00x, and keep the
top speedup at or above 50.00x. If one command drops below that floor, fix
the command, rerun the suite, or stop using the stale number as release
evidence.
Read benchmark claims carefully¶
When you compare against upstream Picard, record:
the exact command line;
input size and sort order;
Picard version;
turbo-picardcommit;CPU, memory, storage, and container or conda environment;
parity result for the output you are measuring.
Do not generalize a benchmark from one command to another. MarkDuplicates,
SortSam, FASTQ conversion, metrics collectors, and VCF utilities stress
different parts of the system.
The public benchmark suite currently reports 32 command speedups, covering the
native or partly native data-processing commands in the matrix.
AccelerationStatus, doctor, and explain are exempt because they are
status/preflight commands with no Picard data-processing runtime to benchmark.
Two benchmark scopes are deliberately narrow: CollectMultipleMetrics is benchmarked with
PROGRAM=CollectQualityYieldMetrics, and chart-producing child programs still
use the chart-output disclosure below.
Benchmark exemption: AccelerationStatus — status/preflight command with no Picard data-processing runtime to benchmark.
Benchmark exemption: doctor — status/preflight command with no Picard data-processing runtime to benchmark.
Benchmark exemption: explain — status/preflight command with no Picard data-processing runtime to benchmark.
Genome-scale evidence¶
Micro-benchmarks in tools/bench_suite.py are useful for regression tracking,
but a real switching decision should include at least one larger shard that
resembles the workflow:
whole-genome or exome BAM size, not only 100k-read fixtures;
the same duplicate-marking, sorting, and FASTQ conversion commands the workflow uses;
wall time, peak RSS, and cloud cost estimates from the same machine profile.
Refresh public evidence with:
python3 tools/audit_real_data.py \
--input-bam /data/representative-wgs.bam \
--input-source-url https://example.org/accession.bam \
--input-source-commit example-accession \
--output-dir benchmarks/real-data/wgs-representative/evidence \
--dataset-id wgs-representative \
--picard-command "mamba run -p /opt/conda/envs/picard picard" \
--turbo-picard-command ./target/release/picard \
--skip-build
Pair that bundle with python3 tools/bench_suite.py on the same commands so
performance claims stay tied to parity-checked outputs.
Large-input speed evidence¶
Use large-input speed evidence for market comparisons against tools such as
riker. Keep it separate from the small release-candidate parity fixtures so
readers can tell which numbers are smoke checks and which numbers came from a
workflow-sized BAM.
For the QC overlap surface, stage the HG02675_4x BAM described in
benchmarks/riker-comparison/README.md and run:
python3 tools/bench_qc_vs_riker.py \
--sample-id HG02675_4x \
--input-bam /mnt/scratch/HG02675_4x/input.bam \
--reference-fasta /mnt/scratch/refs/hg38.fa \
--output-dir benchmarks/riker-comparison/evidence/HG02675_4x \
--repeats 3 \
--measure-rss \
--skip-build
The report includes per-profile Picard, turbo-picard, and riker wall
time, optional RSS, total profile speedups, and an explicit overlap leader/gap
summary for wgs-only and wgs-bundle. If riker wins a profile, record
that gap and the next bottleneck instead of using the smoke fixture as a
substitute for WGS-scale evidence.
Real-data parity evidence¶
Synthetic benchmark speedups are not enough for switching decisions. Real-data
parity evidence is tracked in benchmarks/real-data/manifest.json and checked
with:
python3 tools/verify_real_data_evidence.py
python3 tools/verify_real_data_evidence.py --release-ready
The checked-in release evidence currently includes GATK’s public NA12878
mitochondrial test BAM, the same shard converted to CRAM with a pinned
reference, and Picard’s public SNVQ metrics test BAM.
For GitHub-hosted real-data inputs, the evidence must cite a
/blob/<commit>/ URL and the full 40-character Git commit SHA, not a branch
name or short hash.
GATK NA12878 mitochondrial evidence:
source:
https://github.com/broadinstitute/gatk/blob/e8c49f600b06c658e0fa9bf67256340ebb46bc48/src/test/resources/org/broadinstitute/hellbender/tools/mutect/mito/NA12878.bamcommit:
e8c49f600b06c658e0fa9bf67256340ebb46bc48local SHA-256:
70ea2e429805a75ce6007a32ba176ea7c697a398e0c39a9d58aaaa30e1ed86c3evidence report:
benchmarks/real-data/gatk-na12878-mito/evidence/real-data-comparison.mdscope caveat:
GATK public NA12878 mitochondrial test BAM.minimum input threshold:
1000000bytes
GATK NA12878 mitochondrial CRAM evidence:
source:
https://github.com/broadinstitute/gatk/blob/e8c49f600b06c658e0fa9bf67256340ebb46bc48/src/test/resources/org/broadinstitute/hellbender/tools/mutect/mito/NA12878.bamcommit:
e8c49f600b06c658e0fa9bf67256340ebb46bc48local SHA-256:
68931e7cea6e9a35029cfed3638d0d8ea2c4bb662b4d83232968da247b68f7bcevidence report:
benchmarks/real-data/gatk-na12878-mito-cram/evidence/real-data-comparison.mdscope caveat:
GATK public NA12878 mitochondrial test BAM converted to CRAM with assembly38 mt-only reference.minimum input threshold:
910668bytes
Picard SNVQ metrics evidence:
source:
https://github.com/broadinstitute/picard/blob/fc0b08410d38a10afd08e467dab74bf5e2e71310/testdata/picard/sam/snvq_metrics_test.bamcommit:
fc0b08410d38a10afd08e467dab74bf5e2e71310local SHA-256:
be0daa7cb8e9ce11f2f68ac3db8c229d530736aaf7b80df3669fdb00779c06b3evidence report:
benchmarks/real-data/picard-snvq/evidence/real-data-comparison.mdscope caveat:
Picard public SNVQ metrics test BAM.minimum input threshold:
1000000bytes
Both saved runs pass Picard 3.4.0 on ViewSam, CleanSam,
CollectQualityYieldMetrics, CollectAlignmentSummaryMetrics, and
MarkDuplicates. The GATK NA12878 mitochondrial bundle also passes
AddOrReplaceReadGroups with a SAM record and read-group header digest,
BuildBamIndex with an exact BAI binary digest, RevertSam with a
reverted SAM record digest, SortSam with a coordinate-sorted record multiset
digest, SamToFastq with first-end, second-end, and unpaired FASTQ outputs
matched byte-for-byte, and CollectInsertSizeMetrics with the stable metrics
table and insert-size histogram digest matched against Picard. It also passes
ValidateSamFile by matching the summary validation histogram and Picard’s
non-zero exit code on that input. The CRAM bundle passes CleanSam,
CollectQualityYieldMetrics, CollectInsertSizeMetrics, MarkDuplicates,
SortSam, and AddOrReplaceReadGroups on the same public mitochondrial
shard with native CRAM I/O. The release check must cover this command set
somewhere in the pinned evidence:
AddOrReplaceReadGroups, BuildBamIndex, CleanSam,
CollectAlignmentSummaryMetrics, CollectInsertSizeMetrics,
CollectQualityYieldMetrics, MarkDuplicates, RevertSam, SamToFastq, SortSam,
ValidateSamFile, ViewSam. These fixtures are useful release evidence, but they
are still small. They are not proof for every dataset a lab might process. Add
larger public shards or representative private data before claiming the tool is
proven for a whole production dataset. The release-ready check also requires
enough pinned input data that one tiny fixture cannot carry the release by
itself.