Problem
After #1085 and #1088 the report phase is report_lcov, and it is the only
place left that still forks per file and loops per line in Bash.
Per tracked file it runs three awk forks (lines, functions, and the branch
extractor once it moves) plus two Bash loops: the per-function span scan that
decides FNDA, and the per-arm scan that decides BRDA.
Measured on Bash 3.2 arm64, 128 tracked src/*.sh files:
| 128 files |
|---|
report_lcov total | 2785 ms |
of which compute_branch_hits | 1479 ms |
of which extract_functions | 535 ms |
of which awk_lcov_lines | 440 ms |
bare awk fork x128 (the floor) | ~350 ms |
The remaining cost is almost entirely fork overhead and Bash glue: the awk
work itself is a rounding error, as #1088 showed when the same shape took the
stats phase from 2585 ms to 153 ms.
Proposal
One awk invocation for the whole report, driven by the same manifest #1088
introduced. Every record a file needs — SF, FN/FNDA/FNF/FNH,
BRDA/BRF/BRH, DA/LF/LH, end_of_record — comes out of a single
pass that already has the source lines and the propagated hit counts in hand.
This needs the function scanner and the branch extractor in function form so
both the per-file API and the batch pass call the same code, not a copy.
Verification
Byte-identical LCOV against a fixed corpus, with hits, plus the existing unit
tests. The branch extractor has already been ported and diffed against the
Bash implementation over all 463 shell files in the repo with no mismatch.
Problem
After #1085 and #1088 the report phase is
report_lcov, and it is the onlyplace left that still forks per file and loops per line in Bash.
Per tracked file it runs three awk forks (lines, functions, and the branch
extractor once it moves) plus two Bash loops: the per-function span scan that
decides
FNDA, and the per-arm scan that decidesBRDA.Measured on Bash 3.2 arm64, 128 tracked
src/*.shfiles:report_lcovtotalcompute_branch_hitsextract_functionsawk_lcov_linesawkfork x128 (the floor)The remaining cost is almost entirely fork overhead and Bash glue: the awk
work itself is a rounding error, as #1088 showed when the same shape took the
stats phase from 2585 ms to 153 ms.
Proposal
One awk invocation for the whole report, driven by the same manifest #1088
introduced. Every record a file needs —
SF,FN/FNDA/FNF/FNH,BRDA/BRF/BRH,DA/LF/LH,end_of_record— comes out of a singlepass that already has the source lines and the propagated hit counts in hand.
This needs the function scanner and the branch extractor in function form so
both the per-file API and the batch pass call the same code, not a copy.
Verification
Byte-identical LCOV against a fixed corpus, with hits, plus the existing unit
tests. The branch extractor has already been ported and diffed against the
Bash implementation over all 463 shell files in the repo with no mismatch.