Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
26 changes: 19 additions & 7 deletions cli/commands/diff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
}

Expand Down
24 changes: 18 additions & 6 deletions cli/validators/docs-diff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
}

Expand Down