Further profiling and optimisation #636#647
Merged
Chemaclass merged 8 commits intoApr 30, 2026
Merged
Conversation
…3.0 compatibility
…che on init Why: - generate_file_html unconditionally re-ran get_coverage_class after both branches already assigned class, undoing part of the cache lookup. - bashunit::coverage::init did not reset the stats cache globals, leaving stale data on re-init.
Why: - get_cached_stats already falls back to get_file_stats when the cache is empty, so the if/else dispatch in report_text, report_html, and generate_file_html was duplicating the same code path. - Single call site shrinks three duplicated parsers down to one and removes a dead branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Related #636
PRs #643 and #644 addressed the
is_executable_lineconsolidation andcompute_file_coveragesingle-pass. This PR adds further optimisations on top: eliminating remainingsed/grepsubshells, pre-loading source files into arrays, caching stats across reports, and using pure Bash 3.0 string operations inextract_functions(replacing[[ =~ ]]).Changes
sed -nper-line spawns — read source files once into indexed arrays inget_hit_linesandgenerate_file_html, replacing per-line sed calls with array lookupsprecompute_file_statscomputes executable/hit/pct once viacompute_file_coverage, shared byreport_text,report_html, andget_percentage; O(1) lookup with string-based cacheextract_functions— pure string operations replace[[ =~ ]]+BASH_REMATCH;printf '%s'replacesechoinis_executable_line;((++var))convention from Fix post-increment causing silent exit under set -e #619compute_file_coverage,report_lcov, andget_function_coveragenow read files once and iterate withforinstead ofwhile IFS= readis_executable_line—casestatements handle comments, braces, control keywords, and standalone)without spawning grep; falls through to grep for complex patterns onlyprecompute_file_statsandget_cached_statsPer-Component Breakdown
Test workload: 15 source files, ~1200 hit entries, full report generation (text + lcov + html)
is_executable_line(8000 calls)extract_functions(15 calls)report_textreport_lcovreport_htmlHyperfine Statistical Benchmark
Measured with warmup run + 3 measured runs each, on a macOS machine:
13.4x faster confirmed by hyperfine. The original code took ~2 minutes to generate all three reports; after the optimisations it takes ~9 seconds.
Caveats
EPOCHREALTIMEtimestamps in a benchmark harness — directional rather than statistically rigorous. The hyperfine full-pipeline comparison is the headline number.Checklist
CHANGELOG.mdto reflect the new feature or fix