Agent: programmer (
programmer)
Confidence: 93%
Cost: $1.2271
Duration: 4m 11s
Task ID:04a42c9f-0dc0-468b-bf9c-38a654d3b5ef
★ Insight ─────────────────────────────────────
這次優化的核心數學原理:
Running Sum 技巧:原本每次
recalcAvg()都執行Σ(docLengths.values()) / N,需要遍歷整個 Map。改為維護一個totalDocLength累加器,每次 upsert 只做totalDocLength += (newLen - oldLen),這是經典的 incremental statistics 技巧。時機的精確性很關鍵:在
upsert()中,removeFromInverted()只清理 inverted index,不會 動docLengthsMap。所以在增量更新時,舊長度仍可從docLengths.get(doc.id)讀到。如果讀取順序錯了(先 set 再 get),就會拿到新值,造成 BM25 分數偏移。複雜度改善:
rebuild()批量插入 N 個文件時,原本是 O(N²)(每次 upsert 都掃全部已有文件),現在是 O(N)(每次 upsert 只做常數時間運算)。對於 1000+ 文件的 narrative index,這是顯著的效能改善。─────────────────────────────────────────────────
修改摘要
檔案:src/memory/search-index.ts(+15 行, -18 行)
改動內容:
- 新增
private totalDocLength = 0欄位追蹤所有文件 token 長度總和 upsert():用isUpdateflag +oldLen/newLen差值增量更新totalDocLength,直接計算avgDocLengthremove():從totalDocLength減去被移除文件的長度,totalDocs--,重算avgDocLengthclear():重置totalDocLength = 0- 完全移除了
recalcAvg()方法(不再需要遍歷整個 Map)
驗證結果:
tsgo --noEmit:通過npm test:90 個測試檔、1108 個測試全數通過git diff只改src/memory/search-index.ts一個檔案