Repository navigation
1.2.2: faster builds (working directory read once, header listings remembered, one mock collection per test) - #1383
Merged
Merged
Conversation
ProjectPaths reads Dir.pwd on every lookup, cache hits included. The specs ask for the working directory to be read once, and add WorkingDir.chdir, which answers for the directory it changes to and then for the one it left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ProjectPaths asked the operating system for the working directory on every path lookup: tens of thousands of times a build, at 20-70 us each on macOS. WorkingDir now reads it once. Ceedling changes directory only through WorkingDir.chdir, which forgets it going in and coming out, and the Dependencies plugin uses it. The specs, which change directory in-process, forget it on every Dir.chdir. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mock's header is found by listing every header on its test's search paths, and those directories are listed again on every call. The specs ask for a directory outside the build root to be listed once per test build, for one under the build root to be listed every time, and for each test build to start with fresh listings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Finding a mock's header listed every directory on its test's search paths afresh, three times a test plus once per mock: a third of a no-op rebuild. IncludePathinator now keeps each directory's listing for the test build. Directories under the build root are listed every time, since the build writes there, and TestInvoker starts each test build with fresh listings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The planner rebuilt a test's mock header collection for every mock it resolved, though nothing in that loop changes the test's search paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Planning rebuilt the mock header collection for every mock a test includes. It is now built at the first real mock and shared by the rest; a test with only Partial mocks builds none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FileSystemWrapper#cd, which plugins can reach, used FileUtils.cd and so left the remembered working directory stale inside its block. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI summary · e615c23 · ✅ 25/25 jobs passed · nearest baseline 4f6f1b6 (master)
Diff coverage: 100.00% (37/37 changed lines).
All legs (examples / failures / pending)
Jobs
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
External tests on complex projects ran at 1.2.1's speed or slightly slower, even though the
TEST_SOURCE_FILE()fix should have made them faster. Profiling master against v1.2.1 found three causes, and this PR fixes all three. Every measured run is now faster than on both master and v1.2.1, and generated mocks are byte-identical to master's.ProjectPathsasked the operating system for the working directory (Dir.pwd) on every path lookup, cache hits included. That's about 15,000 calls for one test and 45,000–79,000 for a 200-test build, at 20–70 µs each on macOS. 1.2.1 made 3 calls a run. This was the one new cost since 1.2.1.WorkingDirmodule (lib/ceedling/filesystem/working_dir.rb) reads the directory once.WorkingDir.chdiris the one sanctioned way to change directory: it forgets the remembered directory going in and coming out. The Dependencies plugin's commands andFileSystemWrapper#cdgo through it.spec/support/working_dir_tracking.rbforgets the remembered directory on everyDir.chdir, in specs only.IncludePathinator#ordered_header_fileskeeps each directory's listing for one test build. Ordering, de-duplication and every caller are unchanged.TestInvokerforgets the listings at the start of each test build, after thepre_test_buildhook.Headers that a hook generates outside the build root partway through a build are out of scope; that's tracked as its own issue. There's no Changelog entry: the working-directory cost arrived during this prerelease cycle, and the other two fixes change nothing a user configures.
Measurements
Medians of interleaved runs on macOS, Ruby 3.2.2. The synthetic project has 200 tests, two mocks and a
TEST_SOURCE_FILE()per test, and 210 include directories.Share of the change: the working-directory memo removes the slowdown since 1.2.1, the header listings give about a third off every no-op rebuild, and the planner change adds a few percent. On Linux a
Dir.pwdcall costs about 1 µs, so the first fix matters less there.Test plan
WorkingDir.chdir's forgetting, or any branch of the header-listing logic, fails specs.🤖 Generated with Claude Code