[perf] Consolidated performance evidence: September 2026
Open
Nobody has claimed this yet.
status/needs-triage
type/automation
type/performance
- Dominant language
- Python
- Stars
- 3.8k
- Forks
- 362
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 132
Description
Performance Scan - 2026-09-14
Automated scan of src/apm_cli/ for algorithmic performance anti-patterns.
3 finding(s) identified.
Findings
[B] Linear scan inside a loop -- src/apm_cli/commands/uninstall/engine.py:189-260
- Current: O(n*m) --
_stage_shared_local_survivorsloops over
packages_to_remove(n) and calls_surviving_local_refs_at_install_path
(line 196), which itself linearly scans all ofsurviving_dependencies(m)
on every call. The same helper is also called again per-package inside
_dry_run_uninstall(line 756), doubling the cost on--dry-run. - Proposed: O(n+m) -- pre-index
surviving_dependenciesonce into a
dict[install_path, list[DependencyReference]]before either loop, then
do an O(1) dict lookup per package instead of an O(m) scan. - Fix: Build a
install_path -> [local survivors]dict once outside both
loops inengine.pyand replace the repeated calls to
_surviving_local_refs_at_install_pathwith a lookup against that dict.
[E] Heavy top-level imports on CLI command modules -- src/apm_cli/commands/install.py:1-53
- Current:
apm.commands.installis imported eagerly by
src/apm_cli/cli.py:38for every CLI invocation, and it in turn performs
53 top-level imports (agent_plugins, copilot_plugins, install.argv,
install.artifactory_resolver, install.dry_run_plan, install.errors,
install.gitlab_resolver, install.helpers.ref_reuse,
install.manifest_helpers, install.finalization, install.helpers.security_scan,
etc.) that are only exercised when the user actually runsapm install.
Every other subcommand (e.g.apm view,apm config) pays this import
cost at process startup. - Proposed: defer the install-only heavy imports (artifactory_resolver,
gitlab_resolver, dry_run_plan, manifest_helpers, security_scan) to inside
theinstall()command function body, keeping only what's needed for
Click registration (theinstallcallable itself) at module import time. - Fix: Move the imports in
src/apm_cli/commands/install.pylines 14-51
that are only referenced inside theinstall/helper function bodies to
local imports inside those functions, following the existing pattern
already used forclose_install_contextsdeferral elsewhere in the file.
[C] Unconditional directory walk fallback -- src/apm_cli/install/services.py:863-880
- Current: O(n) unconditional -- when
pack_filesis empty (older bundle
withoutbundle_filesmetadata), the code falls back to
bundle_dir.rglob("*")and computes a fullsha256hash of every file in
the bundle on every deploy for that bundle, with no caching between
target loops in the same install run. - Proposed: this fallback is correctly gated behind
if not pack_files:
already (fast-path skip when bundle metadata is present), so this is a
low-priority, borderline finding -- it only fires for legacy bundles
lackingbundle_files, not on every install. Noting for awareness only;
no action required unless legacy-bundle installs become a hot path.
Scan coverage
- src/apm_cli/ (484 files scanned)
- Patterns checked: A (quadratic loops), B (linear scan in loop),
C (unconditional expensive ops), D (redundant config parsing),
E (heavy top-level imports), F (sequential independent I/O)
Generated by Daily Performance Scanner · copilot · auto · 105.2 AIC · ⌖ 6.75 AIC · ⊞ 10.1K · ◷
- expires on Sep 21, 2026, 1:42 AM UTC
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/apm_cli/commands/uninstall/engine.py:189-260 and 756, then inspect src/apm_cli/commands/install.py:1-53 and src/apm_cli/cli.py:38. Confirm the repeated survivor scans and eager install imports before making changes. Done means indexing survivors once, deferring install-only imports, and preserving the existing CLI behavior; the legacy bundle fallback is awareness-only.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, performance
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100