Problem
build::strip_comments round-trips the flattened artifact through shfmt's JSON AST so that # inside a heredoc is not mistaken for a comment. Timing the three stages on the current artifact:
| stage | time |
|---|
shfmt -ln=bash --to-json | 0.50s |
jq 'walk(…)' | 5.11s |
shfmt -i 2 --from-json | 0.39s |
The AST is 57 MB. walk is defined in jq's own language and rebuilds every node of it, so the filter costs more than the parse and the re-print combined.
Fix
Two changes, same filter:
(.. | objects | select(has("Comments")) | .Comments) |= map(select(…)) — .. is jq's C-level recursive descent, and only the matched paths are updatedjq -c — the intermediate is 57 MB that shfmt immediately re-parses, so pretty-printing it is wasted
Measured on the full pipeline, three runs each:
old 6.46s 6.54s 6.64s
new 2.52s 2.61s 2.54s
End to end, ./build.sh goes 7.63s → 4.04s, and the two artifacts are byte-identical (checksum files differ only in the embedded output path, which is the directory each was built into).
Where it pays
Every Build & Verify CI job on two platforms, every release, and test_built_binary_stays_below_640_kib, which was the seventh-slowest test in the suite at 7.81s.
Problem
build::strip_commentsround-trips the flattened artifact through shfmt's JSON AST so that#inside a heredoc is not mistaken for a comment. Timing the three stages on the current artifact:shfmt -ln=bash --to-jsonjq 'walk(…)'shfmt -i 2 --from-jsonThe AST is 57 MB.
walkis defined in jq's own language and rebuilds every node of it, so the filter costs more than the parse and the re-print combined.Fix
Two changes, same filter:
(.. | objects | select(has("Comments")) | .Comments) |= map(select(…))—..is jq's C-level recursive descent, and only the matched paths are updatedjq -c— the intermediate is 57 MB that shfmt immediately re-parses, so pretty-printing it is wastedMeasured on the full pipeline, three runs each:
End to end,
./build.shgoes 7.63s → 4.04s, and the two artifacts are byte-identical (checksum files differ only in the embedded output path, which is the directory each was built into).Where it pays
Every
Build & VerifyCI job on two platforms, every release, andtest_built_binary_stays_below_640_kib, which was the seventh-slowest test in the suite at 7.81s.