Skip to content

perf: reduce test-suite execution time (tracking) #761

Description

@Chemaclass

Tracking: reduce test-suite execution time

Status 2026-07-14 (round 2 complete)

All round-2 child issues have landed (#772#775); per-change before/after numbers are recorded in each PR. Round 1 (#767#771) remains as history below.

Round 1 recap (commit 1ae3e82, macOS bash 3.2.57, Apple Silicon):

  • 100 trivial tests: ~0.68s (was ~5.0s) — per-test framework overhead ~48ms → ~6.8ms (~7x).
  • Full suite --parallel: ~52s for 1250 tests. The dominant remaining cost is the 258 nested ./bashunit cold starts in the acceptance suite, not per-test overhead.

The remaining work is the cold-start frontier plus two small fork leftovers (below); the per-test hot path is now largely fork-free.

Child issues — round 1 (done)

Child issues — round 2 (done)

Smaller leftovers

Not worth their own issue; folded into a round-2 cleanup PR:

Next frontier (needs measurement before filing)

Spun out into #798 — the acceptance suite's 258 nested ./bashunit cold-start runs now dominate wall-clock. See #798 for candidate directions and the measure-first plan.

Constraints for all work

  • Bash 3.0+ compatibility is non-negotiable (no declare -A, no [[ ]], no ${var,,}, no negative array indexing, no &>>). The perf target machine IS bash 3.2 on macOS.
  • TDD, quality gate (./bashunit tests/, ./bashunit --parallel tests/, make sa, make lint, shfmt -w .) on every PR.
  • One issue per PR; no batching unrelated changes.

Shared benchmark protocol

Run before and after each change, report numbers in the PR:

mkdir -p /tmp/bashunit-bench
for i in $(seq 1 100); do echo "function test_noop_$i() { assert_true true; }"; done > /tmp/bashunit-bench/noop100_test.sh
time ./bashunit --no-parallel /tmp/bashunit-bench/noop100_test.sh   # current: ~0.68s

# fork census (external binaries per run)
PS4='+X ${BASH_SOURCE##*/}:$LINENO ' bash -x ./bashunit --no-parallel /tmp/bashunit-bench/noop100_test.sh \
  2>/tmp/bashunit-bench/trace.txt >/dev/null
grep -oE ' (perl|base64|grep|sed|mktemp|rm|date) ' /tmp/bashunit-bench/trace.txt | sort | uniq -c

For assertion-heavy paths (#772) use 100 tests x 10 assert_equals; for tags (#773) use 100 tagged tests with --tag foo.

Also considered and NOT filed: lazy-sourcing large optional modules (coverage.sh, learn.sh) at startup. Sourcing all of src/ measures only ~28ms, so the win across 258 nested cold starts is ~5-8s and it complicates the single-file release build. Revisit as part of the "next frontier" item above.

Original baseline (commit 4d80e7c, for history)

  • 100 trivial tests took ~5.0s (~48ms/test): 2x perl clock forks, 3x base64 pipelines, 1x grep+sed provider probe, 1x base64 -d decode, ~12-14 $(...) subshells per test.
  • Sequential full suite >4 min; --parallel ~48s with no default job cap.

Line references valid at commit 49064ed and will drift.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Fields

No fields configured for Feature.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions