From ba0c8748165a37b5b4bed2811f582beb20e4e8e7 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 01:07:11 +0000 Subject: [PATCH] Pre-compute basenames and use Sets for test matching Replaced multiple nested `.filter().some()` loops in `cli/commands/diff.mjs` and `cli/validators/docs-diff.mjs` with a single-pass cross-comparison using Sets and pre-computed basenames for code objects. This avoids redundant string processing overhead (`basename` calls inside inner loops) and multiple O(N*M) passes, significantly improving the performance of comparing documented tests against code tests. --- .jules/bolt.md | 4 ++++ cli/commands/diff.mjs | 26 +++++++++++++++++++------- cli/validators/docs-diff.mjs | 24 ++++++++++++++++++------ 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 8aef41f..90bd5a2 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -8,3 +8,7 @@ ## 2024-05-24 - Pre-compile RegExp in nested loops **Learning:** Instantiating `new RegExp()` inside nested array methods like `.filter` and `.some` creates a severe O(N*M) performance bottleneck, especially when matching two large lists (e.g., documented tests vs. actual test files). **Action:** Always pre-compile regular expressions and derived strings into an array of "matcher" objects outside of the loop before iterating, which shifts the instantiation cost from O(N*M) to O(N). + +## 2024-05-30 - [Optimize N*M Array Comparisons] +**Learning:** In string-heavy O(N*M) nested array comparisons (like `.filter().some()` to compare test files), calling string processing functions like `basename()` repeatedly for the same item during every pass is a major bottleneck. +**Action:** Avoid redundant string processing overhead by pre-computing string formats (like basenames) into objects outside the loop, and use `Set`s for single-pass cross-comparisons instead of multiple O(N*M) array iterations. diff --git a/cli/commands/diff.mjs b/cli/commands/diff.mjs index 856eea1..cb59ffc 100644 --- a/cli/commands/diff.mjs +++ b/cli/commands/diff.mjs @@ -363,17 +363,29 @@ function diffTests(dir, config = {}) { }; }); - const matches = (matcher, codeRel) => { - const subject = matcher.hasSlash ? codeRel : basename(codeRel); - return matcher.rx.test(subject); - }; + // PERFORMANCE OPTIMIZATION: Avoid redundant string processing overhead by + // pre-computing basenames outside the loop, and replace multiple nested + // .filter().some() passes with a single-pass cross-comparison using Sets. + const codeObjects = codeArr.map(c => ({ rel: c, base: basename(c) })); + const matchedDocs = new Set(); + const matchedCode = new Set(); + + for (const doc of docMatchers) { + for (const code of codeObjects) { + const subject = doc.hasSlash ? code.rel : code.base; + if (doc.rx.test(subject)) { + matchedDocs.add(doc.original); + matchedCode.add(code.rel); + } + } + } return { title: 'Test Files', icon: '🧪', - onlyInDocs: docMatchers.filter(m => !codeArr.some(c => matches(m, c))).map(m => m.original), - onlyInCode: codeArr.filter(c => !docMatchers.some(m => matches(m, c))), - matched: docMatchers.filter(m => codeArr.some(c => matches(m, c))).map(m => m.original), + onlyInDocs: docMatchers.filter(m => !matchedDocs.has(m.original)).map(m => m.original), + onlyInCode: codeObjects.filter(c => !matchedCode.has(c.rel)).map(c => c.rel), + matched: docMatchers.filter(m => matchedDocs.has(m.original)).map(m => m.original), }; } diff --git a/cli/validators/docs-diff.mjs b/cli/validators/docs-diff.mjs index f9fef2b..bd54037 100644 --- a/cli/validators/docs-diff.mjs +++ b/cli/validators/docs-diff.mjs @@ -188,15 +188,27 @@ function diffTests(dir, config) { }; }); - const matches = (matcher, codeRel) => { - const subject = matcher.hasSlash ? codeRel : basename(codeRel); - return matcher.rx.test(subject); - }; + // PERFORMANCE OPTIMIZATION: Avoid redundant string processing overhead by + // pre-computing basenames outside the loop, and replace multiple nested + // .filter().some() passes with a single-pass cross-comparison using Sets. + const codeObjects = codeArr.map(c => ({ rel: c, base: basename(c) })); + const matchedDocs = new Set(); + const matchedCode = new Set(); + + for (const doc of docMatchers) { + for (const code of codeObjects) { + const subject = doc.hasSlash ? code.rel : code.base; + if (doc.rx.test(subject)) { + matchedDocs.add(doc.original); + matchedCode.add(code.rel); + } + } + } return { title: 'Test Files', - onlyInDocs: docMatchers.filter(m => !codeArr.some(c => matches(m, c))).map(m => m.original), - onlyInCode: codeArr.filter(c => !docMatchers.some(m => matches(m, c))), + onlyInDocs: docMatchers.filter(m => !matchedDocs.has(m.original)).map(m => m.original), + onlyInCode: codeObjects.filter(c => !matchedCode.has(c.rel)).map(c => c.rel), }; }