Improve performance of pytest discovery for large test suites#25974
Merged
Conversation
…covery by dicts to improve discovery performance for large, flat test suites
Author
|
@microsoft-github-policy-service agree company="Codasip" |
There was a problem hiding this comment.
Pull request overview
This PR addresses #25973 by optimizing how the vscode_pytest plugin builds the pytest discovery tree for very large suites (especially heavily-parameterized tests), reducing the pathological O(n^2) behavior caused by repeated list membership scans during tree construction.
Changes:
- Replaced per-node
childrenlists with aChildrencontainer backed by a dict keyed byid_to make repeated inserts/deduplication effectivelyO(1). - Updated tree-building code paths to use
Children.add()instead of list membership checks +append(). - Switched discovery JSON serialization to a custom encoder that also knows how to serialize
Childrencontainers back to JSON arrays (preserving the expected payload shape).
Show a summary per file
| File | Description |
|---|---|
| python_files/vscode_pytest/init.py | Reworks test-tree child storage to a dict-backed container and updates JSON encoding to keep discovery output compatible while improving performance. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 1
Member
|
Thanks for putting together this PR! Just this one comment by copilot and then I think we are good and I can approve. Appreciate it! |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eleanorjboyd
enabled auto-merge (squash)
May 29, 2026 20:58
Yoyokrazy
previously approved these changes
May 29, 2026
eleanorjboyd
previously approved these changes
May 29, 2026
pwang347
approved these changes
May 29, 2026
dmitrivMS
approved these changes
May 29, 2026
eleanorjboyd
added a commit
that referenced
this pull request
Jul 24, 2026
## Problem The discovery/run testing telemetry added in #25980 emitted its numeric performance fields — `totalDurationMs`, `testCount` (`UNITTEST.DISCOVERY.DONE`) and `durationMs`, `requestedCount` (`UNITTEST.RUN.DONE`) — in the **properties** bag instead of the **measures** argument of `sendTelemetryEvent`. These fields are annotated `isMeasurement: true`, and telemetry ingestion drops measurement-annotated fields that arrive as properties. Verified against production telemetry: across ~46M `unittest.discovery.done` events in the last 14 days, **zero** carried `totalDurationMs` or `testCount` (in either `Properties` or `Measures`), while the string categoricals (`mode`, `trigger`, `failureCategory`) came through fine. The `mode`/`trigger` fields survive because they're strings; the numeric ones silently vanish. This means there is currently **no duration signal** to evaluate the recent pytest discovery performance work (#25974, #25982) — the measurements were never actually recorded. The correct pattern is confirmed by `NATIVE_FINDER_PERF`, which passes its numbers via the measures (2nd) argument and lands them cleanly in the `Measures` column. ## Fix Move the numeric measurement fields to the `measures` (2nd) argument of `sendTelemetryEvent` at all five emit sites: - `resultResolver.ts` — `DISCOVERY.DONE` success path (`totalDurationMs`, `testCount`) - `controller.ts` — `DISCOVERY.DONE` project-error path (`totalDurationMs`) and `RUN.DONE` legacy path (`durationMs`, `requestedCount`) - `workspaceTestAdapter.ts` — `DISCOVERY.DONE` legacy-error path (`totalDurationMs`) - `projectTestExecution.ts` — `RUN.DONE` project path (`durationMs`, `requestedCount`) Also removed these fields from the event **property** type definitions (the `__GDPR__` annotations are unchanged and already correctly mark them `isMeasurement: true`) and added notes so they aren't reintroduced as properties. ## Verification - `tsc`: no new type errors from these changes. - `eslint` + `prettier`: clean on all changed files. - Unit tests pass: `resolveDiscovery` (5), project `RUN.DONE` telemetry (2), and workspace discovery (5). ## Impact Once a build with this fix ships, `totalDurationMs`/`testCount`/`durationMs`/`requestedCount` will populate in the `Measures` column, enabling the before/after discovery-performance comparison (sliced by `testCount` bucket × `mode`). No user-facing behavior change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.
Fixes #25973
At the moment this PR demonstrates how to fix the problem, however I'll be happy to change the code however you see fit.