Skip to content

perf(runner): resolve a test's source location only when needed - #1356

Merged
Chemaclass merged 1 commit into
mainfrom
feat/1346-cache-function-lines-per-file
Sep 9, 2026
Merged

Chemaclass merged 1 commit into
mainfrom
feat/1346-cache-function-lines-per-file

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #1346

Every test forked a subshell to read its own definition line, building a <file>:<line> that only a failure message and a report row ever read. On macOS arm64 (bash 3.2.57) that is 1.08ms per test.

💡 Changes

  • Carry the file and function name with the test identity and resolve the location on the two paths that render it. A plain run pays nothing; a --report-* run pays what it did before. A 500-test file went from 2.75s to 2.40s.
  • The issue proposed caching the lines in a per-file map. Both shapes measured worse on Bash 3.2 and the commit records why: a parallel-array map costs 7.5ms/test (arrays are linked lists, indexing is O(i)), a single-string map 19ms/test (${var#*pat} is quadratic).
  • The inputs are not exported, since every consumer is a fork. A standalone bashunit assert … therefore stops reporting the location of whichever test launched it — one acceptance snapshot pinned that leak and loses the line.
  • Correct the fork-budget rule: its 0.46ms figure for a bare $( ) predates arm64, where the same measurement is 1.1-1.4ms.

https://claude.ai/code/session_01EXYWTGLjf7qM8Ru3GakDRm

Every test forked a subshell to read its own definition line:
`$(shopt -s extdebug; declare -F "$fn")`, 1.08ms per call on macOS
arm64 (bash 3.2.57). It produced `<file>:<line>` for a failure message
most tests never emit, and for a report row that add_test discards
before reading when no report is configured. A 500-test file spent
0.35s of 2.75s on it.

Carry the file and function name instead and resolve on the two paths
that render the location. A plain run pays nothing; a run with
`--report-*` pays what it paid before.

The two obvious alternatives are both worse on Bash 3.2, so they are
recorded here rather than retried: a parallel-array map scanned per
test made a 500-test file 7.5ms/test against 6.3ms, because a Bash 3
array is a linked list and indexing is O(i); a single-string map read
with `${map#*$'\n'$fn$'\t'}` made it 19ms/test, because prefix removal
against a leading `*` is quadratic in the string length.

The inputs are not exported. Every consumer runs in a fork, which
inherits them regardless, while an exec'd process gets a function name
its own shell never defined -- which is how a standalone `bashunit -a
assert_same` came to print the location of whichever test had launched
it. It now prints none, and the acceptance snapshot that pinned the
leak loses that line.

perf-fork-budget.md's 0.46ms figure for a bare `$( )` predates arm64
and read as "a subshell is not worth removing"; it now carries the
arm64 numbers.

Closes #1346

Claude-Session: https://claude.ai/code/session_01EXYWTGLjf7qM8Ru3GakDRm
@Chemaclass Chemaclass added the enhancement New feature or request label Sep 9, 2026
@Chemaclass Chemaclass self-assigned this Sep 9, 2026
@Chemaclass
Chemaclass merged commit 2de660f into main Sep 9, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1346-cache-function-lines-per-file branch September 9, 2026 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant