Replies: 1 comment 1 reply
|
dsh-hang.cpuprofile |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
摘要
长会话(大量
assistant/chunk)下 TokenMeter 产生 O(n²) 退化:每次session.append都会使session.events快照失效(eventsSnapshot = undefined),而 TokenMeter 的session/event监听器只取 session 参数、弃用了回调本就携带的 event,随后在_sync()里访问session.eventsgetter 触发全量日志拷贝——每 append 一次就 O(n) 重建快照,却只消费 1 个新事件。发帖人实测 32K 事件时 active meter 1657ms vs inactive 476ms(约 3.5 倍、二次方增长)。复现步骤
dsh,创建会话,开启 TokenMeter(默认 bundle 下已激活)。assistant/chunkappend),或回放长会话日志。根因(源码定位,rc.6)
session.events是"失效即全量重建"的快照 —@deepseek-ai/dsh-session/lib/index.js:get events() { this.eventsSnapshot ??= Object.freeze([...this.log]); return this.eventsSnapshot; }—— 快照缺失时对完整日志做浅拷贝(O(n));append():this.log.push(event); this.eventsSnapshot = void 0;—— 每个 append 都使快照失效;模型每输出一个 chunk 就是一次 append。session/event回调本来就携带新事件,监听器却弃用 — 同文件:const callbackArgs = [this, event],invokeContainedSessionObservers(..., "session/event", ..., callbackArgs)—— 监听器能直接拿到刚 append 的 event;@deepseek-ai/dsh-token-meter/lib/index.jsL424-426:ctx.on("session/event", (session) => { if (this.states.has(session)) this._sync(session); })—— 只取 session 参数。_sync()每次访问session.events触发全量重建 —dsh-token-meter/lib/index.jsL485-504:快照刚被 append 失效,
session.eventsgetter 重建整个日志副本,而循环通常只 fold 1 个新事件 → 每 append O(n),总计 O(n²)。注意:fold 逻辑本身已是增量设计(
consumedEvents游标),瓶颈不在 fold 而在快照失效-重建。_estimateProviderAssistant(L578-594)在assistant/message时还会按sourceEventSeqs读session.events[seq](L587)——替换溯源需求,修复时需保留该能力。建议修复
方案 A(推荐)· 消费回调携带的 event,绕开快照重建:
ctx.on("session/event", (session, event) => { if (this.states.has(session)) this._foldEvent(session, state, event); })(增量 fold 单个新事件),仅冷启动/补偿时全量_sync();_estimateProviderAssistant的 L587 提供 O(1) 按序访问(如给 dsh-session 增加eventAt(seq)——log 是数组可直接下标,或在回调内收集本次 sourceSeqs 需要的旧事件)。热路径零快照重建,消除二次方项。方案 B · 优化 dsh-session 的 events getter 缓存:append 后不立即失效快照(延迟重建/不可变增量视图)。改动在公共 API 语义层,影响面大,但所有
session.events消费者(含 UI 会话渲染)共同受益。方案 C · token-meter 微任务合并:多个 append 合并为一次同步。治标不治本,快照重建次数虽降但每次仍 O(n)。
影响
环境
验证材料
dsh-session/lib/index.jsL1397-1400/L1470-1471/L1464-1472 与dsh-token-meter/lib/index.jsL424-426/L485-504/L578-594;_sync访问session.events→ O(n) 拷贝 → 总 O(n²)。First analysis of discussion #238. Happy to open a PR with fix option A.
All reactions