diff --git a/.jules/bolt.md b/.jules/bolt.md index 989a6ff..3ff460e 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -1,3 +1,6 @@ ## 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-14 - Time-Series O(log n) Search Pattern +**Learning:** `src/data/sources/dnsePublic.ts` previously used a `.filter((b) => b.time <= asOf)` to clip historical arrays. This turned what should be a fast slice operation into an O(n) scan over entire time-series data. +**Action:** Used the already-available `findLastBarIndex` (which implements binary search) and `.slice()` to truncate the arrays in `O(log n)` time instead, massively speeding up lookups for arrays representing long timelines. diff --git a/src/data/sources/dnsePublic.ts b/src/data/sources/dnsePublic.ts index ee39639..0ddeec0 100644 --- a/src/data/sources/dnsePublic.ts +++ b/src/data/sources/dnsePublic.ts @@ -88,7 +88,10 @@ function clipBars(bars: Bar[]): Bar[] { asOfClock.getStore()?.asOfSec != null || isAsOfOverridden(); if (!hasOverride) return bars; const asOf = nowSec(); - return bars.filter((b) => b.time <= asOf); + + // ⚡ Bolt: Optimize O(n) filter to O(log n) binary search for large time-series arrays + const idx = findLastBarIndex(bars, asOf); + return idx === -1 ? [] : bars.slice(0, idx + 1); } export async function getStockOhlcv(