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 @@ -19,3 +19,7 @@
## 2025-03-16 - Consolidating chained array iterations in mathematical routines
**Learning:** Found a hot path in `packages/core/src/engines/parameterTransforms.ts` (`fitWaldAnalytic`) where an array of length N was traversed multiple times through `map`, `filter`, and multiple `reduce` calls to compute intermediate values (n, s1, sInv). Because this runs many times in a loop over ~1000 items, the overhead of creating intermediate arrays and performing 4 independent O(N) passes was significant (~630ms in benchmarks). Collapsing this into a single `for` loop eliminated all array allocations and reduced execution time by ~15-20x to ~35ms.
**Action:** In high-frequency, performance-sensitive mathematical loops, avoid chaining `.map()`, `.filter()`, and `.reduce()`. Instead, use a standard `for` loop to accumulate multiple variables simultaneously in a single O(N) pass, completely eliminating intermediate array allocations.

## 2024-05-19 - Avoid Chained Array Methods in Hot Paths
**Learning:** Chained array methods like `.map().filter().map()` are frequently used in config parsing utilities (`coerce.ts`). They generate multiple intermediate arrays which create garbage collection thrashing in hot paths (like sampling or scheduling).
**Action:** Replace `Array.prototype.map().filter()` with a single `for...of` loop and a standard `if` statement to construct arrays directly.
91 changes: 60 additions & 31 deletions packages/core/src/utils/coerce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ export function toFiniteNumber(value: unknown, fallback: number): number {
}

export function toNumberArray(value: unknown, fallback: number[]): number[] {
const out = asArray(value).map((entry) => Number(entry)).filter((entry) => Number.isFinite(entry)) as number[];
// ⚡ Bolt: Replaced chained .map().filter() with single loop to avoid intermediate array allocations
const out: number[] = [];
for (const entry of asArray(value)) {
const num = Number(entry);
if (Number.isFinite(num)) {
out.push(num);
}
}
return out.length > 0 ? out : fallback;
}

Expand Down Expand Up @@ -80,15 +87,26 @@ export function resolveBlockScreenSlotValue(
}

export function asStringArray(value: unknown, fallback: string[]): string[] {
const list = asArray(value).map((item) => asString(item)).filter((item): item is string => Boolean(item));
// ⚡ Bolt: Replaced chained .map().filter() with single loop to avoid intermediate array allocations
const list: string[] = [];
for (const entry of asArray(value)) {
const str = asString(entry);
if (str) {
list.push(str);
}
}
return list.length > 0 ? list : [...fallback];
}

export function asPositiveNumberArray(value: unknown, fallback: number[]): number[] {
const list = asArray(value)
.map((entry) => Number(entry))
.filter((entry) => Number.isFinite(entry) && entry > 0)
.map((entry) => Math.floor(entry));
// ⚡ Bolt: Replaced chained .map().filter().map() with single loop to avoid intermediate array allocations
const list: number[] = [];
for (const entry of asArray(value)) {
const num = Number(entry);
if (Number.isFinite(num) && num > 0) {
list.push(Math.floor(num));
}
}
return list.length > 0 ? list : [...fallback];
}

Expand Down Expand Up @@ -141,17 +159,28 @@ export function coerceInstructionInsertions(value: unknown): InstructionInsertio
const pages = toInstructionScreenSpecs(raw.pages);
if (pages.length === 0) continue;
const whenRaw = asObject(raw.when);
const blockIndex = asArray(whenRaw?.blockIndex)
.map((item) => Number(item))
.filter((item) => Number.isInteger(item))
.map((item) => Math.floor(item));
const blockLabel = asArray(whenRaw?.blockLabel)
.map((item) => asString(item))
.filter((item): item is string => Boolean(item));
const blockType = asArray(whenRaw?.blockType)
.map((item) => asString(item))
.filter((item): item is string => Boolean(item))
.map((item) => item.toLowerCase());
// ⚡ Bolt: Replaced chained .map().filter() with single loops for blockIndex, blockLabel, and blockType to avoid intermediate array allocations
const blockIndex: number[] = [];
for (const item of asArray(whenRaw?.blockIndex)) {
const num = Number(item);
if (Number.isInteger(num)) {
blockIndex.push(Math.floor(num));
}
}
const blockLabel: string[] = [];
for (const item of asArray(whenRaw?.blockLabel)) {
const str = asString(item);
if (str) {
blockLabel.push(str);
}
}
const blockType: string[] = [];
for (const item of asArray(whenRaw?.blockType)) {
const str = asString(item);
if (str) {
blockType.push(str.toLowerCase());
}
}
const isPractice = typeof whenRaw?.isPractice === "boolean" ? whenRaw.isPractice : undefined;
const when: InstructionInsertionWhen | undefined =
blockIndex.length > 0 || blockLabel.length > 0 || blockType.length > 0 || typeof isPractice === "boolean"
Expand Down Expand Up @@ -237,20 +266,20 @@ export function toInstructionScreenSpecs(value: unknown): InstructionScreenSpec[
const title = asString(raw.title) ?? undefined;
const html = asString(raw.html) ?? undefined;
const text = asString(raw.text) ?? asString(raw.body) ?? asString(raw.content) ?? undefined;
const actions = asArray(raw.actions)
.map((entry): InstructionScreenAction | null => {
const actionRaw = asObject(entry);
if (!actionRaw) return null;
const label = asString(actionRaw.label);
if (!label) return null;
const action = (asString(actionRaw.action) ?? "continue").toLowerCase();
return {
...(asString(actionRaw.id) ? { id: asString(actionRaw.id) as string } : {}),
label,
action: action === "exit" ? "exit" : "continue",
};
})
.filter((entry): entry is InstructionScreenAction => Boolean(entry));
// ⚡ Bolt: Replaced chained .map().filter() for actions with a single loop to avoid intermediate array allocations
const actions: InstructionScreenAction[] = [];
for (const entry of asArray(raw.actions)) {
const actionRaw = asObject(entry);
if (!actionRaw) continue;
const label = asString(actionRaw.label);
if (!label) continue;
const action = (asString(actionRaw.action) ?? "continue").toLowerCase();
actions.push({
...(asString(actionRaw.id) ? { id: asString(actionRaw.id) as string } : {}),
label,
action: action === "exit" ? "exit" : "continue",
});
}
if (!html && !text) return null;
return {
...(title ? { title } : {}),
Expand Down