@@ -99,7 +99,7 @@ export class PythonResultResolver implements ITestResultResolver {
9999 // if any tests exist, they should be populated in the test tree, regardless of whether there were errors or not.
100100 // parse and insert test data.
101101
102- // CLEANUP: Clear existing maps to remove stale references before rebuilding
102+ // Clear existing mappings before rebuilding test tree
103103 this . runIdToTestItem . clear ( ) ;
104104 this . runIdToVSid . clear ( ) ;
105105 this . vsIdToRunId . clear ( ) ;
@@ -179,18 +179,13 @@ export class PythonResultResolver implements ITestResultResolver {
179179 }
180180
181181 /**
182- * PERFORMANCE CRITICAL: This method rebuilds the entire test case array
183- * Currently called for EVERY test result, causing O(n*m*k) complexity
184- * TODO: Replace with cached lookup or direct item access
182+ * Collect all test case items from the test controller tree.
183+ * Note: This performs full tree traversal - use cached lookups when possible.
185184 */
186185 private collectAllTestCases ( ) : TestItem [ ] {
187186 const testCases : TestItem [ ] = [ ] ;
188187
189- // PERFORMANCE PROBLEM: This rebuilds the ENTIRE test case array
190- // MIDDLE OPERATION: O(m) where m = number of top-level test items in controller
191188 this . testController . items . forEach ( ( i ) => {
192- // RECURSIVE TREE TRAVERSAL: getTestCaseNodes(i) is O(depth * children)
193- // For parameterized tests with subtests, this can be very deep
194189 const tempArr : TestItem [ ] = getTestCaseNodes ( i ) ;
195190 testCases . push ( ...tempArr ) ;
196191 } ) ;
@@ -199,15 +194,14 @@ export class PythonResultResolver implements ITestResultResolver {
199194 }
200195
201196 /**
202- * Find a test item efficiently using the pre-built maps, with fallback to tree search only if needed .
203- * This avoids the O(k) search for 99% of cases while still handling edge cases .
197+ * Find a test item efficiently using cached maps with fallback strategies .
198+ * Uses a three-tier approach: direct lookup, ID mapping, then tree search .
204199 */
205200 private findTestItemByIdEfficient ( keyTemp : string ) : TestItem | undefined {
206- // FAST PATH: Try the O(1) lookup first
201+ // Try direct O(1) lookup first
207202 const directItem = this . runIdToTestItem . get ( keyTemp ) ;
208203 if ( directItem ) {
209- // VALIDATION: Check if the TestItem is still valid (hasn't been deleted from controller)
210- // This prevents using stale references
204+ // Validate the item is still in the test tree
211205 if ( this . isTestItemValid ( directItem ) ) {
212206 return directItem ;
213207 } else {
@@ -216,18 +210,16 @@ export class PythonResultResolver implements ITestResultResolver {
216210 }
217211 }
218212
219- // FALLBACK: Try vsId mapping
213+ // Try vsId mapping as fallback
220214 const vsId = this . runIdToVSid . get ( keyTemp ) ;
221215 if ( vsId ) {
222- // Try to find by VS Code ID directly in the controller
223- // This is still much faster than full tree traversal
216+ // Search by VS Code ID in the controller
224217 let foundItem : TestItem | undefined ;
225218 this . testController . items . forEach ( ( item ) => {
226219 if ( item . id === vsId ) {
227220 foundItem = item ;
228221 return ;
229222 }
230- // Check children only if not found at top level
231223 if ( ! foundItem ) {
232224 item . children . forEach ( ( child ) => {
233225 if ( child . id === vsId ) {
@@ -238,19 +230,18 @@ export class PythonResultResolver implements ITestResultResolver {
238230 } ) ;
239231
240232 if ( foundItem ) {
241- // Cache for next time to avoid this lookup
233+ // Cache for future lookups
242234 this . runIdToTestItem . set ( keyTemp , foundItem ) ;
243235 return foundItem ;
244236 } else {
245- // Clean up stale vsId mapping
237+ // Clean up stale mapping
246238 this . runIdToVSid . delete ( keyTemp ) ;
247239 this . vsIdToRunId . delete ( vsId ) ;
248240 }
249241 }
250242
251- // LAST RESORT: Only do expensive tree traversal if really needed
252- // This should rarely happen with proper discovery
253- console . warn ( `Falling back to expensive tree search for test: ${ keyTemp } ` ) ;
243+ // Last resort: full tree search
244+ console . warn ( `Falling back to tree search for test: ${ keyTemp } ` ) ;
254245 const testCases = this . collectAllTestCases ( ) ;
255246 return testCases . find ( ( item ) => item . id === vsId ) ;
256247 }
@@ -278,11 +269,8 @@ export class PythonResultResolver implements ITestResultResolver {
278269 }
279270
280271 /**
281- * Clean up stale references from maps (optional method for external cleanup)
282- *
283- * Time Complexity: O(n * depth) where n is the number of cached test items and depth
284- * is the average tree depth. This is much more efficient than the original O(n*m*k)
285- * tree rebuilding approach, since it only validates existing cache entries.
272+ * Clean up stale test item references from the cache maps.
273+ * Validates cached items and removes any that are no longer in the test tree.
286274 */
287275 public cleanupStaleReferences ( ) : void {
288276 const staleRunIds : string [ ] = [ ] ;
@@ -454,22 +442,11 @@ export class PythonResultResolver implements ITestResultResolver {
454442
455443 /**
456444 * Process test execution results and update VS Code's Test Explorer with outcomes.
457- *
458- * CURRENT PERFORMANCE ISSUE: For each test result, this method rebuilds the entire test tree
459- * (O(m) traversal) and then searches through all test items (O(k) search). With parameterized
460- * tests producing many results, this becomes O(n*m*k) complexity, eventually causing stack overflow.
445+ * Uses efficient lookup methods to handle large numbers of test results.
461446 */
462447 public _resolveExecution ( payload : ExecutionTestPayload , runInstance : TestRun ) : void {
463- // PERFORMANCE ISSUE: This method has O(n*m*k) complexity that causes stack overflow:
464- // - For each test result (n), we rebuild the entire test tree (m items)
465- // - Then search through all leaf nodes (k nodes) to find the matching test
466- // - With parameterized tests, n can be large, making this exponentially slow
467448 const rawTestExecData = payload as ExecutionTestPayload ;
468449 if ( rawTestExecData !== undefined && rawTestExecData . result !== undefined ) {
469- // Map which holds the subtest information for each test item.
470-
471- // PERFORMANCE FIX: No longer need to rebuild test tree for every result!
472- // Use efficient lookup methods instead
473450 for ( const keyTemp of Object . keys ( rawTestExecData . result ) ) {
474451 const testItem = rawTestExecData . result [ keyTemp ] ;
475452
0 commit comments