From a1b474de898b1e737485dfd641561738ce294343 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 15:33:08 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20sub-interval=20e?= =?UTF-8?q?xtraction=20to=20O(log=20n)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced full-array O(n) `.filter()` and O(n log n) `.sort()` with O(log n) binary search in `intervalCloses` in `src/agent/backtestRunner.ts`. This reduces the CPU overhead when slicing chronologically sorted time-series market data for backtesting intervals. Co-authored-by: toreleon <42534763+toreleon@users.noreply.github.com> --- .jules/bolt.md | 6 +++--- src/agent/backtestRunner.ts | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 989a6ff..48161ba 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,3 @@ -## 2024-05-14 - Time-Series O(log n) Search Pattern -**Learning:** `src/agent/backtestRunner.ts` makes heavy use of `.filter((b) => b.time <= asOf)` to get the latest close price inside loop bounds, changing potentially O(1) loop lookups or O(log n) lookups into repetitive O(n) filtering over large arrays. -**Action:** Expose `findLastBarIndex` in `src/data/sources/dnsePublic.ts` and use binary search or track indices explicitly in tight loops. +## 2024-05-24 - O(log n) over O(n) array operations for Time-Series +**Learning:** Backtest intervals involve frequent repeated lookups on chronologically sorted time-series market data arrays. Existing implementations using `.filter()` and `.sort()` on large `Bar` arrays have an $O(N \log N)$ complexity and unnecessarily reiterate arrays that are already inherently sorted. +**Action:** Replace full-array filters and sorts on `Bar` data with a combination of `findLastBarIndex()` (for $O(\log n)$ boundary lookups) followed by `.slice()`. This pattern is dramatically more CPU-efficient on large historical datasets. diff --git a/src/agent/backtestRunner.ts b/src/agent/backtestRunner.ts index 610ee01..59753e5 100644 --- a/src/agent/backtestRunner.ts +++ b/src/agent/backtestRunner.ts @@ -101,10 +101,16 @@ function parseBacktestInterval(value: string | undefined): { label: string; minu } function intervalCloses(vnindexBars: Bar[], startSec: number, endSec: number, intervalMinutes: number): number[] { - const base = vnindexBars - .filter((b) => b.time >= startSec && b.time <= endSec) - .map((b) => b.time) - .sort((a, b) => a - b); + // ⚡ Bolt: Optimize sub-interval extraction from O(n log n) filter+sort to O(log n) binary search + const startIdx = findLastBarIndex(vnindexBars, startSec - 1) + 1; + const endIdx = findLastBarIndex(vnindexBars, endSec); + + if (startIdx > endIdx || startIdx >= vnindexBars.length || endIdx < 0) { + return []; + } + + const base = vnindexBars.slice(startIdx, endIdx + 1).map((b) => b.time); + const step = Math.max(1, Math.round(intervalMinutes / 30)); if (step === 1) return base;