Problem
bashunit::coverage::extract_functions walks a source file line by line in
Bash and counts braces with two ${line//[^\{]/} substitutions per line.
Bash 3.2 pattern substitution over a whole file is the most expensive thing
left in the report phase, and the report calls this once per file per
renderer (report_text, report_lcov, html_file).
Measured on Bash 3.2 arm64, 128 tracked src/*.sh files, no hits:
| per-file helper | 128 files |
|---|
extract_functions | 2238 ms |
compute_file_coverage | 1534 ms |
compute_branch_hits | 1479 ms |
awk_lcov_lines | 440 ms |
bare awk fork x128 (the floor) | 447 ms |
17.5 ms per file, against a 3.5 ms fork floor.
Proposal
Same state machine, one awk pass — the shape .claude/rules/perf-fork-budget.md
prescribes for file scans, and the one #1059 already used for the line
classifier. Rules stay identical, quirks included (braces are counted without
regard for strings or comments; changing that moves numbers and belongs in its
own issue).
Result
| before | after |
|---|
extract_functions, 128 files | 2238 ms | 399 ms |
report_lcov, 128 files | 5052 ms | 2638 ms |
--coverage --coverage-paths src, 1-test file | 9.23 s | 6.81 s |
Verified byte-identical against the Bash implementation over all 463
git ls-files '*.sh' in the repo, with the differential mutation-checked.
Problem
bashunit::coverage::extract_functionswalks a source file line by line inBash and counts braces with two
${line//[^\{]/}substitutions per line.Bash 3.2 pattern substitution over a whole file is the most expensive thing
left in the report phase, and the report calls this once per file per
renderer (
report_text,report_lcov,html_file).Measured on Bash 3.2 arm64, 128 tracked
src/*.shfiles, no hits:extract_functionscompute_file_coveragecompute_branch_hitsawk_lcov_linesawkfork x128 (the floor)17.5 ms per file, against a 3.5 ms fork floor.
Proposal
Same state machine, one awk pass — the shape
.claude/rules/perf-fork-budget.mdprescribes for file scans, and the one #1059 already used for the line
classifier. Rules stay identical, quirks included (braces are counted without
regard for strings or comments; changing that moves numbers and belongs in its
own issue).
Result
extract_functions, 128 filesreport_lcov, 128 files--coverage --coverage-paths src, 1-test fileVerified byte-identical against the Bash implementation over all 463
git ls-files '*.sh'in the repo, with the differential mutation-checked.