diff --git a/CHANGELOG.md b/CHANGELOG.md index 144357c6..02bc0efa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Changed +- Performance: `--coverage-report-html` no longer forks twice per source line to escape it — 58.7s to 9.5s for 128 files here, with the escaping done once per file and the per-page `wc`, `basename` and `pwd` calls replaced by parameter expansions (#1096) - Performance: the coverage report picks its colours without a subshell per file and per function — the text report over 128 files went from 387ms to 318ms, and 4042ms to 3116ms with `BASHUNIT_COVERAGE_SHOW_FUNCTIONS` on (#1092) ## [0.47.0](https://github.com/TypedDevs/bashunit/compare/0.46.0...0.47.0) - 2026-08-13 diff --git a/src/coverage/html_file.sh b/src/coverage/html_file.sh index 11976435..7d56ac97 100644 --- a/src/coverage/html_file.sh +++ b/src/coverage/html_file.sh @@ -6,7 +6,7 @@ function bashunit::coverage::generate_file_html() { local file="$1" local output_file="$2" - local display_file="${file#"$(pwd)"/}" + local display_file="${file#"$PWD"/}" local executable hit pct class stats stats=$(bashunit::coverage::get_cached_stats "$file") bashunit::coverage::split_stats "$stats" @@ -27,6 +27,16 @@ function bashunit::coverage::generate_file_html() { ((++_fli)) done <"$file" + # And their escaped form, in ONE awk pass for the whole file. Escaping per + # line cost a command substitution and a sed each -- about 22,000 processes + # for this repo, 58.7s of HTML report (#1096). + local -a escaped_lines=() + local _eli=0 _el + while IFS= read -r _el || [ -n "$_el" ]; do + escaped_lines[_eli]="$_el" + ((++_eli)) + done < <(bashunit::coverage::html_escape_file "$file") + # Pre-load test hits data into indexed array (for tooltips) # Index: line number, Value: newline-separated list of "test_file:test_function" # Using indexed array for Bash 3.0 compatibility (no associative arrays) @@ -53,8 +63,7 @@ function bashunit::coverage::generate_file_html() { done < <(bashunit::coverage::get_all_line_tests "$file") # Count total lines and functions - local total_lines - total_lines=$(wc -l <"$file" | tr -d ' ') + local total_lines="${#file_lines[@]}" local non_executable=$((total_lines - executable)) { @@ -65,7 +74,7 @@ function bashunit::coverage::generate_file_html() { EOF - echo " $(basename "$display_file") | Coverage Report" + echo " ${display_file##*/} | Coverage Report" cat <<'EOF'