GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — perf(compile): remove redundant work from instruction placement by sekosen · Pull Request #3379 · microsoft/apm Conversation
|
| project | directories | before | after | speedup | before MB | after MB |
|---|---|---|---|---|---|---|
proj_small |
~6 | 0.25s | 0.24s | 1.0x | 66 | 66 |
proj_1000 |
~1000 | 2.69s | 0.58s | 4.7x | 75 | 74 |
proj_2000 |
~2000 | 7.95s | 0.91s | 8.8x | 85 | 83 |
proj_10000 |
~10000 | 153.11s | 3.70s | 41.3x | 165 | 153 |
Issue: #2969
Human scope-approval comment: #2969 (comment)
Replaces #2878 with a new history and without the excluded symlink behavior change.
Fixes #2969
test(compile): pin placement behavior before the perf fix: unit parity tests, pass on main.test(compile): cover placement and file inclusion through apm compile: end-to-end test through the real CLI, passes on main.perf(compile): remove redundant work from placement: the fix. Existing tests pass unmodified.test(compile): catch regressions of the placement perf fix: regression tests for each optimization. Each was checked to fail when the code it guards is broken.| Criterion | Coverage |
|---|---|
| Repeated mean computation | test_depth_mean_computed_once |
| Unnecessary path resolution | test_file_resolved_once_across_patterns, test_directory_resolved_once_per_call |
| Failure to short-circuit | test_candidate_check_stops_at_first_uncovered_directory |
| Stale caches between calls | test_rel_path_cache_entry_does_not_survive, test_resolved_dir_cache_entry_does_not_survive |
| Parity: files and in-project/external/dangling symlinks | test_context_optimizer_symlinked_files.py, test_compile_placement_parity_e2e.py |
| Parity: excluded paths, hidden roots | test_compile_placement_parity_e2e.py (compilation.exclude, node_modules, .github, untargeted hidden dir) |
Real apm compile coverage |
test_compile_placement_parity_e2e.py |
CompileInventory |
Unchanged |
| Docs | No changes needed; compile docs don't cover placement performance |
resolve() for directories. On Windows, a junction can put an unresolved path into the inventory, so skipping it could change placement. This PR keeps resolve() and caches the result instead.main and this branch were compared on a fixture with in-project, external, dangling, looping and directory symlinks, nested .git, excluded and hidden directories, odd file names, an aliased base dir and emulated Windows junctions, across 41 patterns. No differences.main, generated AGENTS.md files count as project files on the next compile, so a rerun can place instructions differently. Out of scope; the e2e test deletes them between runs.Each commit passes tests/unit/compilation and the compile e2e tests on Python 3.10, 3.12 and 3.14. Lint job checks and ratchet tests pass locally.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Static review identified no blocking issues in the focused optimizations and regression coverage; tests were not executed during this review.
No open issues 🎉
This PR addresses #2969 by reducing repeated work in ContextOptimizer, improving instruction-placement performance on large projects while preserving existing matching and symlink behavior.
Changes:
| File | Description |
|---|---|
tests/unit/compilation/test_context_optimizer_symlinked_files.py |
Pins matching behavior for internal, external, dangling, and looping symlinks. |
tests/unit/compilation/test_context_optimizer_phase3.py |
Adds an exact distribution-score assertion. |
tests/unit/compilation/test_context_optimizer_perf_regressions.py |
Checks cache resets, resolution counts, mean computation, and short-circuiting. |
tests/integration/test_compile_placement_parity_e2e.py |
Checks placement and file inclusion through the in-process CLI. |
src/apm_cli/compilation/context_optimizer.py |
Adds path caches and removes redundant scoring and coverage work. |
Review effort: Balanced
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Cover how symlinked files match applyTo patterns (in-project, outside the project, dangling, colliding with a real file, and symlink loops on Python < 3.13) and pin the exact distribution score. All of these pass on main. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Run the real CLI on a project with ordinary files, in-project, outside and dangling symlinks, excluded paths and a .github hidden root, and pin the matched directories and generated AGENTS.md files. Passes on main. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Large projects with overlapping scoped applyTo patterns spent most of compile time repeating the same work in ContextOptimizer: - cache each file's project-relative path instead of resolving it per pattern check - resolve each directory once instead of on every coverage check - compute the depth mean once instead of once per directory - stop checking a placement candidate at its first uncovered directory Both new caches are cleared whenever the project structure is analyzed. Matching and placement results are unchanged; existing tests and the tests from the previous two commits pass without changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Fail if the per-call caches leak between optimize_instruction_placement calls, the depth mean is recomputed per directory, a candidate check keeps going after its first miss, or a file or directory is resolved more than once. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
@microsoft-github-policy-service agree |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
a7a0098 to
2dd6155
Compare
|
Thank you for contributing this performance optimization. Issue #2969 currently has status/needs-design. Although a later comment records approval of a bounded performance-only scope, the issue's status label has not been updated to status/accepted. Please coordinate with Daniel Meppiel (@danielmeppiel) to reconcile the issue's recorded decision and status before proceeding. If the approved scope does not cover this change, open an issue for maintainer review and acceptance first (https://github.com/microsoft/apm/blob/main/CONTRIBUTING.md). This PR is labelled status/deferred until then. The requested reviewers include Daniel Meppiel (@danielmeppiel) and Sergio Sisternes (@sergio-sisternes-epam). Generated by autopilot-pr-triage-worker. This comment is AI-generated and may contain errors. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Daniel Meppiel (@danielmeppiel), you approved the performance-only scope for #2969 on October 19 in this comment. The issue still has The PR stays within that scope. It doesn't touch symlink or containment handling, and the description maps each "Done when" item to a test. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
At least 0 approving reviews are required to merge this pull request.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
apm compile is very slow on large monorepos with scoped applyTo patterns (quadratic placement cost)
There was an error while loading. Please reload this page.