chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
# 首消息性能优化报告
|
||||
|
||||
**日期**: 2026-03-23
|
||||
**优化目标**: 降低首消息(冷启动)Agent 响应延迟
|
||||
**优化前**: ~1662ms
|
||||
**优化后**: ~349ms
|
||||
**提升幅度**: **79%**
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题分析
|
||||
|
||||
### 1.1 原始性能数据
|
||||
|
||||
首消息 `ensureEngineForRequest` 耗时分解:
|
||||
|
||||
```
|
||||
ensureEngine 总耗时: 1662ms
|
||||
├── parseCtxServers: 5ms
|
||||
├── syncMcp: 1315ms ← 主要瓶颈(79%)
|
||||
└── getOrCreate: 342ms
|
||||
├── memory: 231ms
|
||||
└── init: 102ms
|
||||
```
|
||||
|
||||
### 1.2 瓶颈定位
|
||||
|
||||
| 阶段 | 耗时 | 占比 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `syncMcpConfigToProxyAndReload` | 1315ms | 79% | MCP 代理同步,首消息必须等待 |
|
||||
| `ensureMemoryReadyForSession` | 231ms | 14% | Memory 服务初始化 |
|
||||
| `engine.init` | 102ms | 6% | ACP 引擎进程启动 |
|
||||
| 其他 | 14ms | 1% | 配置解析、MCP 提取等 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 优化方案
|
||||
|
||||
### 2.1 优化一:MCP Proxy Bridge 预热
|
||||
|
||||
**原理**: 在服务 `init()` 时后台预热 MCP proxy bridge,避免首消息同步阻塞。
|
||||
|
||||
**代码位置**: `src/main/services/engines/unifiedAgent.ts`
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 🚀 性能优化:后台预热 MCP proxy bridge
|
||||
* 在 init() 时调用,避免首包 syncMcp 阻塞 ~1.3s
|
||||
*/
|
||||
private warmupMcpBridge(): void {
|
||||
(async () => {
|
||||
try {
|
||||
const { syncMcpConfigToProxyAndReload } = await import("../packages/mcp");
|
||||
// 使用空配置预热(仅启动默认服务如 chrome-devtools)
|
||||
await syncMcpConfigToProxyAndReload({});
|
||||
log.info("[UnifiedAgent] ✅ MCP proxy bridge 预热完成");
|
||||
} catch (err) {
|
||||
log.warn("[UnifiedAgent] MCP proxy bridge 预热失败:", err);
|
||||
}
|
||||
})().catch(() => {});
|
||||
}
|
||||
```
|
||||
|
||||
**调用时机**: 在 `init()` 方法末尾调用,与其他预热任务(Engine 预热、Memory 预热)并行执行。
|
||||
|
||||
### 2.2 优化二:syncMcp 与 ensureMemoryReady 并行执行
|
||||
|
||||
**原理**: 当 MCP 配置变更且需要创建新引擎时,将 `syncMcp` 和 `ensureMemoryReady` 并行执行。
|
||||
|
||||
**代码位置**: `src/main/services/engines/unifiedAgent.ts` → `ensureEngineForRequest()`
|
||||
|
||||
```typescript
|
||||
// 🚀 性能优化:只有在 MCP 配置变更时才调用 syncMcpConfigToProxyAndReload
|
||||
// 同时,如果需要创建新引擎(无现有引擎),并行执行 ensureMemoryReady
|
||||
const needCreateEngine = !existingEngine || !existingEngine.isReady;
|
||||
let memoryReadyPromise: Promise<void> | null = null;
|
||||
|
||||
if (mcpChanged) {
|
||||
const syncStart = Date.now();
|
||||
try {
|
||||
const { syncMcpConfigToProxyAndReload } = await import("../packages/mcp");
|
||||
const syncPromise = syncMcpConfigToProxyAndReload(requestMcpServersEarly);
|
||||
|
||||
// 🚀 性能优化:如果需要创建新引擎,并行执行 ensureMemoryReady
|
||||
if (needCreateEngine && memoryService.isInitialized()) {
|
||||
memoryReadyPromise = memoryService.ensureMemoryReadyForSession()
|
||||
.then(() => {
|
||||
log.debug(`⏱️ [PERF] ensureMemoryReady 并行完成: ${Date.now() - syncStart}ms`);
|
||||
})
|
||||
.catch((err) => {
|
||||
log.warn("[UnifiedAgent] Memory sync check failed:", err);
|
||||
});
|
||||
}
|
||||
|
||||
await syncPromise;
|
||||
} catch (e) {
|
||||
log.warn("[UnifiedAgent] 动态同步 MCP 配置到 proxy 失败:", e);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**`getOrCreateEngine` 方法修改**:
|
||||
|
||||
```typescript
|
||||
async getOrCreateEngine(
|
||||
projectId: string,
|
||||
effectiveConfig: AgentConfig,
|
||||
memoryReadyPromise?: Promise<void> | null, // 新增参数
|
||||
): Promise<AcpEngine> {
|
||||
// ...
|
||||
|
||||
// 🚀 性能优化:如果已有并行的 memoryReadyPromise,直接等待它
|
||||
if (memoryReadyPromise) {
|
||||
await memoryReadyPromise;
|
||||
} else if (memoryService.isInitialized()) {
|
||||
await memoryService.ensureMemoryReadyForSession();
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 已有优化(复用)
|
||||
|
||||
以下优化在之前已实现,本次优化复用:
|
||||
|
||||
1. **快速路径 1**: 无配置变更 → 直接返回现有引擎(7ms)
|
||||
2. **快速路径 2**: MCP 未变更 → 跳过 syncMcp
|
||||
3. **Engine 预热池**: 预热 claude-code 和 qimingcode 引擎
|
||||
4. **Memory 预热**: `init()` 时后台执行 `ensureMemoryReadyForSession()`
|
||||
|
||||
---
|
||||
|
||||
## 3. 测试对照
|
||||
|
||||
### 3.1 测试环境
|
||||
|
||||
- **应用版本**: 0.9.1
|
||||
- **测试时间**: 2026-03-23 17:53
|
||||
- **测试场景**: 重启应用后发送首条消息
|
||||
|
||||
### 3.2 优化前日志(2026-03-20)
|
||||
|
||||
```
|
||||
ensureEngine 总耗时: 1662ms
|
||||
├── parseCtxServers: 5ms
|
||||
├── syncMcp: 1315ms
|
||||
└── getOrCreate: 342ms
|
||||
├── memory: 231ms
|
||||
└── init: 102ms
|
||||
```
|
||||
|
||||
### 3.3 优化后日志(2026-03-23)
|
||||
|
||||
```
|
||||
[17:52:55] [info] 🔥 后台预热 Engine: claude-code
|
||||
[17:52:55] [info] 🔥 后台预热 Engine: qimingcode
|
||||
[17:52:55] [info] ✅ 预热 Engine 就绪,等待复用: claude-code
|
||||
[17:52:56] [info] ✅ MCP proxy bridge 预热完成
|
||||
[17:52:58] [info] ✅ 预热 Engine 就绪,等待复用: qimingcode
|
||||
|
||||
[17:53:34] 首消息请求到达
|
||||
[17:53:34] [debug] ⏱️ [ensureEngine][PERF] 解析 context_servers 耗时: 6ms
|
||||
[17:53:34] [info] ⏱️ [PERF] 走完整路径: 无现有引擎, MCP变更(新7个)
|
||||
[17:53:34] [debug] ⏱️ [PERF] ensureMemoryReady 并行完成: 2ms
|
||||
[17:53:34] [info] ⏱️ [PERF] syncMcp 完成: 耗时 2ms | 并行memory=true
|
||||
[17:53:34] [debug] ⏱️ [ensureEngine][PERF] 提取 real MCP servers 耗时: 0ms
|
||||
[17:53:34] [debug] ⏱️ [ensureEngine][PERF] ensureBridgeStarted(有MCP) 耗时: 0ms
|
||||
[17:53:34] [debug] ⏱️ [getOrCreateEngine][PERF] 等待并行 ensureMemoryReady 完成: 231ms
|
||||
[17:53:34] [debug] ⏱️ [getOrCreateEngine][PERF] engine.init 耗时: 105ms
|
||||
[17:53:34] [info] ⏱️ [getOrCreateEngine][PERF] 总耗时: 336ms | 使用并行memory=true
|
||||
[17:53:34] [info] ⏱️ [ensureEngine][PERF] 总耗时: 349ms | 并行优化=true
|
||||
[17:53:34] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 362ms
|
||||
```
|
||||
|
||||
### 3.4 性能对比表
|
||||
|
||||
| 指标 | 优化前 | 优化后 | 提升幅度 |
|
||||
|------|--------|--------|----------|
|
||||
| `syncMcp` | 1315ms | 2ms | **99.8%** ↓ |
|
||||
| `ensureEngine` 总耗时 | 1662ms | 349ms | **79%** ↓ |
|
||||
| `/computer/chat` 总耗时 | ~1700ms | 362ms | **79%** ↓ |
|
||||
|
||||
### 3.5 优化后耗时分解
|
||||
|
||||
```
|
||||
ensureEngine 总耗时: 349ms
|
||||
├── parseCtxServers: 6ms
|
||||
├── syncMcp: 2ms ← 预热后从 1315ms 降至 2ms
|
||||
├── extractReal: 0ms
|
||||
├── ensureBridge: 0ms
|
||||
└── getOrCreate: 341ms
|
||||
├── memory: 231ms ← 与 syncMcp 并行执行
|
||||
└── init: 105ms
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 优化效果总结
|
||||
|
||||
### 4.1 关键收益
|
||||
|
||||
1. **MCP Proxy Bridge 预热**: 消除首消息 ~1.3s 阻塞
|
||||
2. **并行执行**: Memory 准备与 MCP 同步重叠执行
|
||||
3. **Engine 预热池**: 复用已启动的引擎进程
|
||||
|
||||
### 4.2 用户体验改善
|
||||
|
||||
| 场景 | 优化前 | 优化后 |
|
||||
|------|--------|--------|
|
||||
| 首消息响应 | ~1.7s | ~0.35s |
|
||||
| 用户感知 | 明显延迟 | 接近即时 |
|
||||
|
||||
### 4.3 注意事项
|
||||
|
||||
1. **预热时机**: 所有预热任务在 `init()` 末尾启动,不阻塞应用启动
|
||||
2. **内存占用**: 预热引擎会占用额外内存,但通过预热池容量限制(当前 1 个/类型)控制
|
||||
3. **配置变更**: 如果首消息的 MCP 配置与预热配置差异较大,仍需同步,但比冷启动快
|
||||
|
||||
---
|
||||
|
||||
## 5. 相关文件
|
||||
|
||||
- `src/main/services/engines/unifiedAgent.ts` - 主优化文件
|
||||
- `src/main/services/packages/mcp.ts` - MCP proxy 管理
|
||||
- `src/main/services/packages/mcpHelpers.ts` - MCP 配置比较工具
|
||||
|
||||
## 6. 参考资料
|
||||
|
||||
- [ACP Engine 性能优化](./architecture/ACP-ENGINE-PERF-OPTIMIZATION.md)
|
||||
- [深度性能研究报告](./DEEP-RESEARCH-PERF-REPORT-2026-03-20.md)
|
||||
@@ -0,0 +1,121 @@
|
||||
# macOS 平台首消息性能测试报告(重启后新会话)
|
||||
|
||||
**报告日期**: 2026-03-24
|
||||
**测试平台**: macOS
|
||||
**引擎类型**: claude-code
|
||||
**日志来源**: `/Users/apple/.qimingclaw/logs/perf.2026-03-24.log`
|
||||
**参考模板**: `docs/optimization/WINDOWS-FIRST-MESSAGE-PERF-REPORT-2026-03-23.md`
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
本报告针对“重启客户端后首个新会话”进行性能核对。前端显示为 **00:37**,后端 PERF 日志显示两段关键新会话数据:
|
||||
|
||||
1. **16:04 会话**:仅记录到 `sse.firstChunk`,缺少 `sse.end`,无法直接计算完整总时长。
|
||||
2. **16:07 会话**:链路完整,可核算端到端耗时约 **30.163s**(`create-workspace -> sse.end`)。
|
||||
|
||||
### 关键发现
|
||||
|
||||
| 指标 | 16:04 首会话(重启后) | 16:07 完整会话 | 说明 |
|
||||
|-----|------------------|---------------|------|
|
||||
| create-workspace | 2730ms | 275ms | 16:07 工作区阶段明显更快(可能复用) |
|
||||
| /chat 总耗时 | 148ms | 139ms | API 前置开销很小 |
|
||||
| ensureEngine | 127ms | 121ms | 引擎准备并非瓶颈 |
|
||||
| sse 首包延迟(connect->firstChunk) | 10.999s | 12.555s | 首包等待明显 |
|
||||
| sse streaming | 缺失 | 17.333s | 仅 16:07 可核算 |
|
||||
| 端到端(create-workspace->sse.end) | 缺失 | 30.163s | 前端 00:37 高于该值 |
|
||||
|
||||
---
|
||||
|
||||
## 一、测试会话数据
|
||||
|
||||
### 1.1 会话 A(重启后首个新会话,日志不完整)
|
||||
|
||||
| 时间 | session_id | create-workspace | /chat | ensureEngine | sse.connect | sse.firstChunk | sse.end |
|
||||
|-----|-----------|------------------|-------|--------------|-------------|----------------|---------|
|
||||
| 16:04:54 | `e418fa45-a2a5-4a77-8830-abe3449cbc9c` | 2730ms | 148ms | 127ms | 16:04:54.608 | 16:05:05.607 | 缺失 |
|
||||
|
||||
**可计算片段**:
|
||||
- `create-workspace -> sse.firstChunk` = `16:04:54.256 -> 16:05:05.607` = **11.351s**
|
||||
- `sse.connect -> sse.firstChunk` = **10.999s**
|
||||
|
||||
> 由于缺少 `sse.end`,无法直接验证该次会话是否对应前端显示的 00:37。
|
||||
|
||||
### 1.2 会话 B(后续完整新会话)
|
||||
|
||||
| 时间 | session_id | create-workspace | /chat | ensureEngine | sse.connect | sse.firstChunk | sse.end |
|
||||
|-----|-----------|------------------|-------|--------------|-------------|----------------|---------|
|
||||
| 16:07:19 | `13711f68-795e-4517-ab4c-f0284ddc3070` | 275ms | 139ms | 121ms | 16:07:20.000 | 16:07:32.555 | 16:07:49.888 |
|
||||
|
||||
**详细分解**:
|
||||
- `create-workspace -> /chat` = `16:07:19.697 -> 16:07:19.962` = **0.265s**
|
||||
- `sse.connect -> firstChunk` = **12.555s**
|
||||
- `sse streaming` = **17.333s**(日志直接给出)
|
||||
- `create-workspace -> sse.end` = `16:07:19.697 -> 16:07:49.888` = **30.163s**
|
||||
|
||||
---
|
||||
|
||||
## 二、性能分析
|
||||
|
||||
### 2.1 时间结构(基于完整会话 B)
|
||||
|
||||
```text
|
||||
总耗时(create-workspace -> sse.end): 30.163s
|
||||
├── 前置阶段(workspace + chat + engine): ~0.265s(<1%)
|
||||
├── 首包等待(sse.connect -> firstChunk): 12.555s(41.6%)
|
||||
└── 流式输出(firstChunk -> end): 17.333s(57.5%)
|
||||
```
|
||||
|
||||
结论:
|
||||
- 当前主要耗时不在 `ensureEngine`(约 0.12s),而在 **首包等待 + 流式输出阶段**。
|
||||
- 与“历史首消息慢主要在引擎准备”的模式不同,本次瓶颈更偏向模型响应阶段。
|
||||
|
||||
### 2.2 与前端 00:37 的差异
|
||||
|
||||
- 日志可完整核算值:**30.163s**(会话 B)。
|
||||
- 前端显示值:**37s**。
|
||||
- 差异约:**6.8s**。
|
||||
|
||||
可能原因(按优先级):
|
||||
1. 前端计时起点早于 `create-workspace`(例如点击发送或会话初始化前的 UI 阶段)。
|
||||
2. 16:04 首会话虽然日志缺 `sse.end`,但前端仍完成并纳入了完整计时。
|
||||
3. 前端停止计时点晚于 `sse.end`(渲染收尾、状态同步后才停止)。
|
||||
|
||||
---
|
||||
|
||||
## 三、结论与建议
|
||||
|
||||
### 3.1 结论
|
||||
|
||||
1. 重启后首个新会话(16:04)链路不完整,无法直接从后端日志确认 37s。
|
||||
2. 后续完整会话(16:07)总耗时约 **30.163s**,量级接近但低于前端 37s。
|
||||
3. 当前瓶颈集中在 **SSE 首包与流式阶段**,`ensureEngine` 非主要问题。
|
||||
|
||||
### 3.2 建议
|
||||
|
||||
1. 统一前后端计时口径:明确起点/终点并关联同一 `rid/sessionId`。
|
||||
2. 增加 `sse.end` 丢失兜底埋点(取消、断流、窗口关闭等路径也记录结束事件)。
|
||||
3. 增补前端埋点字段:`frontend_timer_start_ts`、`frontend_timer_end_ts`,与后端 PERF 同屏输出便于核对。
|
||||
|
||||
---
|
||||
|
||||
## 附录:原始日志摘录
|
||||
|
||||
```text
|
||||
[2026-03-24 16:04:54.256] [info] [PERF] create-workspace: 2730ms rid=[283ou9vg2]
|
||||
[2026-03-24 16:04:54.569] [info] [PERF] /chat: 148ms rid=68d27799 (parseBody=8ms validate=1ms workspace=1ms engine=127ms chat=11ms)
|
||||
[2026-03-24 16:04:54.608] [info] [PERF] sse.connect session=e418fa45-a2a5-4a77-8830-abe3449cbc9c
|
||||
[2026-03-24 16:05:05.607] [info] [PERF] sse.firstChunk session=e418fa45-a2a5-4a77-8830-abe3449cbc9c
|
||||
|
||||
[2026-03-24 16:07:19.697] [info] [PERF] create-workspace: 275ms rid=[llrt9utmb]
|
||||
[2026-03-24 16:07:19.962] [info] [PERF] /chat: 139ms rid=1107a1f7 (parseBody=7ms validate=1ms workspace=0ms engine=121ms chat=10ms)
|
||||
[2026-03-24 16:07:20.000] [info] [PERF] sse.connect session=13711f68-795e-4517-ab4c-f0284ddc3070
|
||||
[2026-03-24 16:07:32.555] [info] [PERF] sse.firstChunk session=13711f68-795e-4517-ab4c-f0284ddc3070
|
||||
[2026-03-24 16:07:49.888] [info] [PERF] sse.end: 17333ms streaming session=13711f68-795e-4517-ab4c-f0284ddc3070
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: 2026-03-24*
|
||||
*备注: 本报告为 macOS 单平台分析,重点核对前端 00:37 与后端 PERF 的时间差。*
|
||||
@@ -0,0 +1,138 @@
|
||||
# macOS 平台首消息性能测试报告(连续新会话)
|
||||
|
||||
**报告日期**: 2026-03-31
|
||||
**测试平台**: macOS
|
||||
**引擎类型**: qimingcode
|
||||
**日志来源**: `/Users/apple/.qimingclaw/logs/perf.2026-03-31.log`(00:17:30 ~ 00:20:39)
|
||||
**参考模板**: `docs/optimization/MACOS-FIRST-MESSAGE-PERF-REPORT-2026-03-24.md`
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
本报告针对“连续新开会话”的**首条消息首次响应性能**进行核对,口径为:
|
||||
|
||||
- 主要口径:`create-workspace -> sse.firstToken`
|
||||
- 辅助口径:`/chat received -> 首 token`(`/chat` + `sendToFirstUpdate`)
|
||||
|
||||
本轮共观测到 6 次新会话尝试:
|
||||
1. **5 次完整会话**(均包含 `sse.firstToken`)
|
||||
2. **1 次中断会话**(仅 `create-workspace`,未进入 `/chat`)
|
||||
|
||||
### 关键发现
|
||||
|
||||
| 指标 | 本轮结果(5 次完整会话) | 说明 |
|
||||
|-----|------------------|------|
|
||||
| 首次响应(create-workspace -> firstToken) | **平均 9.307s**(8.063s ~ 10.928s) | 用户体感“首字出来”耗时 |
|
||||
| `/chat` 总耗时 | **平均 2.955s**(2.060s ~ 3.697s) | 前置阶段 |
|
||||
| `sendToFirstUpdate` | **平均 6.304s**(5.885s ~ 7.699s) | 首 token 等待阶段,主瓶颈 |
|
||||
| `/chat` 内 `ensureEngine` | **平均 2.042s**(1.367s ~ 3.011s) | A 段内部主耗时 |
|
||||
| 稳定性 | 5/5 完整会话成功 | 本时间窗内未见 `newSession/chat` 报错 |
|
||||
|
||||
---
|
||||
|
||||
## 一、测试会话数据
|
||||
|
||||
### 1.1 五次完整新会话(首消息)
|
||||
|
||||
| 会话 | project_id | rid | session_id | create-workspace | `/chat` | ensureEngine | sessionSetup | sse.connect | sse.firstToken | 首次响应(create->firstToken) |
|
||||
|-----|------------|-----|------------|------------------|---------|--------------|--------------|-------------|----------------|-------------------------------|
|
||||
| S1 | 1564329 | `0d3f44ba` | `ses_2c076bcb0ffeNfAHi2Yiu6tpru` | 00:17:30.613 | 3169ms | 1672ms | 1495ms | 00:17:33.851 | 00:17:39.723 | **9.110s** |
|
||||
| S2 | 1564331 | `b2d8d26f` | `ses_2c075ef03ffeMiHTQKKR4h0FkZ` | 00:18:23.562 | 2652ms | 1982ms | 669ms | 00:18:26.284 | 00:18:32.234 | **8.672s** |
|
||||
| S3 | 1564332 | `1b4b5eeb` | `ses_2c07552afffeFIQODrEZMYpydC` | 00:19:02.567 | 3697ms | 3011ms | 683ms | 00:19:06.309 | 00:19:12.328 | **9.761s** |
|
||||
| S4 | 1564333 | `c00c4d52` | `ses_2c074e299ffe6qfg8LTgbN2lET` | 00:19:32.857 | 2060ms | 1367ms | 692ms | 00:19:35.003 | 00:19:40.920 | **8.063s** |
|
||||
| S5 | 1564334 | `0d815846` | `ses_2c0742965ffebmYiW5e8JIydTk` | 00:20:19.169 | 3199ms | 2179ms | 1019ms | 00:20:22.411 | 00:20:30.097 | **10.928s** |
|
||||
|
||||
### 1.2 中断会话(仅创建工作区)
|
||||
|
||||
| 时间 | rid | 事件 |
|
||||
|-----|-----|------|
|
||||
| 00:18:08.206 | `5mia20hej` | 仅 `create-workspace`,未进入 `/chat`,不纳入首次响应统计 |
|
||||
|
||||
---
|
||||
|
||||
## 二、性能分析(首消息首次响应口径)
|
||||
|
||||
### 2.1 首次响应时间结构(均值)
|
||||
|
||||
```text
|
||||
平均首次响应(create-workspace -> firstToken): 9.307s
|
||||
├── create-workspace -> /chat received: ~0.047s(0.5%)
|
||||
├── A: /chat received -> /chat 返回: 2.955s(31.8%)
|
||||
└── B: /chat 返回 -> firstToken: 6.304s(67.7%)
|
||||
```
|
||||
|
||||
结论:
|
||||
- 若目标是“新会话首条消息尽快出首字”,**B 段是主瓶颈**(约 2/3)。
|
||||
- A 段次之;其中仍以 `ensureEngine` 为主,但总体占端到端首响仅约 22%。
|
||||
|
||||
### 2.2 A 段内部(/chat 阶段)分解
|
||||
|
||||
| 指标 | 平均耗时 | 占 A 段 |
|
||||
|-----|---------|--------|
|
||||
| ensureEngine | 2042ms | 69.1% |
|
||||
| sessionSetup/chat 其余 | 912ms | 30.9% |
|
||||
|
||||
说明:
|
||||
- A 段仍有优化空间,但不是首响的第一优先级。
|
||||
- 本轮 A 段波动(2.060s~3.697s)主要来自 `ensureEngine` 与 `sessionSetup` 抖动。
|
||||
|
||||
### 2.3 抖动观察
|
||||
|
||||
| 阶段 | 最小 | 最大 | 波动特征 |
|
||||
|-----|------|------|---------|
|
||||
| `/chat` | 2060ms | 3697ms | 中等波动 |
|
||||
| `sendToFirstUpdate` | 5885ms | 7699ms | 中等偏高,S5 明显偏慢 |
|
||||
| `firstToken->end_turn` | 8008ms | 25402ms | 该段波动极大(与“首响”无关,但影响整体完成时间) |
|
||||
|
||||
---
|
||||
|
||||
## 三、结论与建议
|
||||
|
||||
### 3.1 结论
|
||||
|
||||
1. 本轮“新会话首条消息首次响应”平均约 **9.3s**。
|
||||
2. 主要瓶颈不在 `/chat` 前置,而在 **`/chat` 返回后等待首 token(B 段)**。
|
||||
3. 本时间窗内 5 次完整会话均成功,未出现上一轮的 `newSession` 内部错误。
|
||||
|
||||
### 3.2 建议(按首响收益排序)
|
||||
|
||||
1. 先优化 `sendToFirstUpdate`(目标先压到 <5s,再冲 <4s)。
|
||||
2. 再收敛 `ensureEngine` 抖动(优先把 3s 档位压回 2s 内)。
|
||||
3. 保留当前 `sse.firstToken` 埋点,后续把优化验收口径统一为 `create-workspace -> sse.firstToken`。
|
||||
|
||||
---
|
||||
|
||||
## 附录:关键日志摘录
|
||||
|
||||
```text
|
||||
[2026-03-31 00:17:30.613] [PERF] create-workspace: 66ms rid=[j197gc94h]
|
||||
[2026-03-31 00:17:33.838] [PERF] /chat: 3169ms rid=0d3f44ba (parseBody=0ms validate=1ms workspace=0ms engine=1672ms chat=1496ms)
|
||||
[2026-03-31 00:17:39.723] [PERF] sse.firstToken session=ses_2c076bcb0ffeNfAHi2Yiu6tpru
|
||||
[2026-03-31 00:17:39.723] [PERF] acp.prompt.sendToFirstUpdate: 5885ms sessionId=ses_2c076bcb0ffeNfAHi2Yiu6tpru
|
||||
|
||||
[2026-03-31 00:18:23.562] [PERF] create-workspace: 49ms rid=[fg7ng07b6]
|
||||
[2026-03-31 00:18:26.269] [PERF] /chat: 2652ms rid=b2d8d26f (parseBody=0ms validate=1ms workspace=0ms engine=1982ms chat=669ms)
|
||||
[2026-03-31 00:18:32.234] [PERF] sse.firstToken session=ses_2c075ef03ffeMiHTQKKR4h0FkZ
|
||||
[2026-03-31 00:18:32.234] [PERF] acp.prompt.sendToFirstUpdate: 5965ms sessionId=ses_2c075ef03ffeMiHTQKKR4h0FkZ
|
||||
|
||||
[2026-03-31 00:19:02.567] [PERF] create-workspace: 51ms rid=[fy8f9owgd]
|
||||
[2026-03-31 00:19:06.296] [PERF] /chat: 3697ms rid=1b4b5eeb (parseBody=1ms validate=0ms workspace=1ms engine=3011ms chat=684ms)
|
||||
[2026-03-31 00:19:12.328] [PERF] sse.firstToken session=ses_2c07552afffeFIQODrEZMYpydC
|
||||
[2026-03-31 00:19:12.328] [PERF] acp.prompt.sendToFirstUpdate: 6033ms sessionId=ses_2c07552afffeFIQODrEZMYpydC
|
||||
|
||||
[2026-03-31 00:19:32.857] [PERF] create-workspace: 72ms rid=[2kfaik1wz]
|
||||
[2026-03-31 00:19:34.980] [PERF] /chat: 2060ms rid=c00c4d52 (parseBody=0ms validate=0ms workspace=1ms engine=1367ms chat=692ms)
|
||||
[2026-03-31 00:19:40.920] [PERF] sse.firstToken session=ses_2c074e299ffe6qfg8LTgbN2lET
|
||||
[2026-03-31 00:19:40.920] [PERF] acp.prompt.sendToFirstUpdate: 5940ms sessionId=ses_2c074e299ffe6qfg8LTgbN2lET
|
||||
|
||||
[2026-03-31 00:20:19.169] [PERF] create-workspace: 46ms rid=[e6dtwydgo]
|
||||
[2026-03-31 00:20:22.398] [PERF] /chat: 3199ms rid=0d815846 (parseBody=0ms validate=1ms workspace=0ms engine=2179ms chat=1019ms)
|
||||
[2026-03-31 00:20:30.097] [PERF] sse.firstToken session=ses_2c0742965ffebmYiW5e8JIydTk
|
||||
[2026-03-31 00:20:30.097] [PERF] acp.prompt.sendToFirstUpdate: 7699ms sessionId=ses_2c0742965ffebmYiW5e8JIydTk
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: 2026-03-31*
|
||||
*备注: 本报告仅针对“新会话首条消息首次响应(first token)”口径,不包含完整回答结束耗时优化判断。*
|
||||
@@ -0,0 +1,69 @@
|
||||
# Session Reuse Fix - 2026-03-24
|
||||
|
||||
## Problem
|
||||
|
||||
连续会话(同一个 project)每次消息都需要重新创建 engine,导致约 3-7 秒的额外延迟。
|
||||
|
||||
## Root Cause
|
||||
|
||||
`detectConfigChange` 比较环境变量时,`OPENCODE_LOG_DIR` 的值不一致:
|
||||
|
||||
- `engineConfigs` 存储的是**本地化后的路径**: `/Users/apple/.qimingclaw/logs`
|
||||
- `resolvedEnv` 来自请求,包含**容器路径**: `/app/container-logs`
|
||||
|
||||
即使两个路径在功能上等价(容器路径会被本地化),字符串比较仍然返回不同,导致 `envChanged: true`,触发 engine 重建。
|
||||
|
||||
## Solution
|
||||
|
||||
在 `detectConfigChange` 方法中添加与 `ensureEngineForRequest` 相同的本地化逻辑:
|
||||
|
||||
```typescript
|
||||
// unifiedAgent.ts lines 927-938
|
||||
let normalizedResolvedEnv = resolvedEnv;
|
||||
if (
|
||||
resolvedEnv?.OPENCODE_LOG_DIR &&
|
||||
!fs.existsSync(resolvedEnv.OPENCODE_LOG_DIR)
|
||||
) {
|
||||
normalizedResolvedEnv = {
|
||||
...resolvedEnv,
|
||||
OPENCODE_LOG_DIR: path.join(os.homedir(), APP_DATA_DIR_NAME, "logs"),
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
然后用 `normalizedResolvedEnv` 进行比较,而非原始的 `resolvedEnv`。
|
||||
|
||||
## Performance Impact
|
||||
|
||||
### Before Fix
|
||||
|
||||
| Request | Engine Time | Path |
|
||||
|---------|-------------|------|
|
||||
| 1st | 3797ms | fullPath (create) |
|
||||
| 2nd | 3063ms | fullPath (recreate - config changed) |
|
||||
| 3rd | 6028ms | fullPath (recreate - config changed) |
|
||||
|
||||
### After Fix
|
||||
|
||||
| Request | Engine Time | Path |
|
||||
|---------|-------------|------|
|
||||
| 1st | 2894ms | fullPath (create) |
|
||||
| 2nd | 5ms | fastPath (reuse) |
|
||||
| 3rd+ | ~5ms | fastPath (reuse) |
|
||||
|
||||
**Improvement**: 连续消息的 engine 准备时间从 3-7 秒降至 ~5ms(99%+ 减少)
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `src/main/services/engines/unifiedAgent.ts`: 添加 `OPENCODE_LOG_DIR` 本地化到 `detectConfigChange` 方法
|
||||
|
||||
## Test Verification
|
||||
|
||||
1. 发送第一条消息到新 project → 观察 `engine.getOrCreate: ~3000ms`
|
||||
2. 发送第二条消息到同一 project → 观察 `engine.ensure: ~5ms`
|
||||
3. 日志应显示 `detectConfigChange: unchanged` 或无 CHANGED 日志
|
||||
|
||||
## Related
|
||||
|
||||
- `ensureEngineForRequest` 中的本地化逻辑 (lines 777-787)
|
||||
- `detectConfigChange` 方法 (lines 912-1030)
|
||||
@@ -0,0 +1,194 @@
|
||||
# Warmup Runtime Config 缓存优化
|
||||
|
||||
**日期**: 2026-03-31
|
||||
**类型**: 性能优化
|
||||
**影响范围**: 新会话首消息响应(连续创建新会话场景)
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题背景
|
||||
|
||||
### 1.1 现象
|
||||
|
||||
连续新开会话时,前 1-2 个会话的 warmup 复用始终 miss,日志出现:
|
||||
|
||||
```
|
||||
[EngineWarmup] ⚠️ 运行时配置不兼容,不复用 warmup(model,apiKey,baseUrl,apiProtocol)
|
||||
warmupModel: '(none)',
|
||||
warmupBaseUrl: '(none)',
|
||||
warmupApiKeySet: false,
|
||||
warmupApiProtocol: '(none)',
|
||||
```
|
||||
|
||||
### 1.2 实测数据(20:52 ~ 20:56,5 个连续新会话)
|
||||
|
||||
| # | 时间 | Warmup | Init(ms) | TTFT(ms) | 总响应(ms) |
|
||||
|---|------|--------|----------|----------|-----------|
|
||||
| 1 | 20:52 | ❌ cold(runtime 不兼容) | 5,705 | 9,507 | 10,389 |
|
||||
| 2 | 20:53 | ❌ cold(runtime 不兼容) | 6,097 | 6,236 | 14,107 |
|
||||
| 3 | 20:54:15 | ✅ reuse | 1,513 | 6,089 | 20,938 |
|
||||
| 4 | 20:54:50 | ✅ reuse | 1,523 | 5,983 | 20,510 |
|
||||
| 5 | 20:55:20 | ✅ reuse | 1,701 | 5,964 | 39,269 |
|
||||
|
||||
前两个会话 warmup miss 导致额外 ~2-4s 冷启动开销。
|
||||
|
||||
### 1.3 根因
|
||||
|
||||
**配置构建时机差异**:
|
||||
|
||||
```
|
||||
init() 阶段:
|
||||
baseConfig = { workspaceDir, engine, env }
|
||||
↓ 缺少 model/apiKey/baseUrl/apiProtocol
|
||||
|
||||
chat() 阶段:
|
||||
effectiveConfig = {
|
||||
...baseConfig,
|
||||
model: mp?.model, ← 来自 model_provider
|
||||
apiKey: mp?.api_key, ← 来自 model_provider
|
||||
baseUrl: mp?.base_url, ← 来自 model_provider
|
||||
apiProtocol: mp?.api_protocol, ← 来自 model_provider
|
||||
mcpServers: freshMcpServers,
|
||||
}
|
||||
```
|
||||
|
||||
- `baseConfig` 在 `init()` 时设置,不含运行时配置
|
||||
- `effectiveConfig` 在每次 `chat()` 请求时动态构建
|
||||
- `warmup.start(baseConfig)` 用的是不含 runtime config 的 baseConfig
|
||||
- `tryReuse()` 检测到 runtime config 不一致 → 回退冷启动
|
||||
|
||||
**影响的三个调用路径**:
|
||||
|
||||
| 调用点 | 触发场景 | seedConfig | 结果 |
|
||||
|--------|---------|-----------|------|
|
||||
| `warmup.start(this.baseConfig)` | `init()` | ❌ 无 | warmup 缺 runtime config |
|
||||
| `warmup.respawn(this.baseConfig)` | 会话结束 | ❌ 无 | 同上 |
|
||||
| `ensureQimingWarmup({reason: "get_or_create_guard"})` | 引擎不存在 | ❌ 无 | 同上 |
|
||||
| `ensureQimingWarmup({seedConfig: {...}})` | warmup 被消费后 refill | ✅ 有 | 正常 |
|
||||
| `ensureQimingWarmup({seedConfig: {...}})` | 冷启动后 refill | ✅ 有 | 正常 |
|
||||
|
||||
**结论**:只有 refill 路径能命中,init / respawn / guard 三个路径永远 miss。
|
||||
|
||||
---
|
||||
|
||||
## 2. 修复方案
|
||||
|
||||
### 2.1 核心思路
|
||||
|
||||
在 `EngineWarmup` 内部缓存最近一次请求的 runtime config(`model/apiKey/baseUrl/apiProtocol`),在 `start()` 创建 warmup 时自动应用缓存值。
|
||||
|
||||
### 2.2 改动清单
|
||||
|
||||
| 文件 | 改动 |
|
||||
|------|------|
|
||||
| `engineWarmup.ts` | 新增 `lastRuntimeConfig` 缓存 + `cacheRuntimeConfig()` 方法 |
|
||||
| `unifiedAgent.test.ts` | 新增 2 个测试场景 |
|
||||
|
||||
### 2.3 具体改动
|
||||
|
||||
#### `engineWarmup.ts`
|
||||
|
||||
**新增字段**:
|
||||
```typescript
|
||||
private lastRuntimeConfig: Pick<
|
||||
AgentConfig,
|
||||
"model" | "apiKey" | "baseUrl" | "apiProtocol"
|
||||
> | null = null;
|
||||
```
|
||||
|
||||
**`start()` 应用缓存**:
|
||||
```typescript
|
||||
const warmupConfig: AgentConfig = {
|
||||
...baseConfig,
|
||||
engine: WARMUP_ENGINE_TYPE,
|
||||
...(this.lastRuntimeConfig
|
||||
? {
|
||||
model: this.lastRuntimeConfig.model || baseConfig.model,
|
||||
apiKey: this.lastRuntimeConfig.apiKey || baseConfig.apiKey,
|
||||
baseUrl: this.lastRuntimeConfig.baseUrl || baseConfig.baseUrl,
|
||||
apiProtocol: this.lastRuntimeConfig.apiProtocol || baseConfig.apiProtocol,
|
||||
}
|
||||
: {}),
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
**`tryReuse()` 三条路径均缓存**:
|
||||
- Runtime mismatch → `cacheRuntimeConfig(effectiveConfig)` → 后续 refill 用新缓存
|
||||
- Warmup hit → `cacheRuntimeConfig(effectiveConfig)` → 保持缓存新鲜
|
||||
- Warmup not ready → `cacheRuntimeConfig(effectiveConfig)` → 同上
|
||||
|
||||
**`dispose()` 清理**:
|
||||
```typescript
|
||||
this.lastRuntimeConfig = null;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置变更时的行为
|
||||
|
||||
缓存的 runtime config 与新请求配置不一致时:
|
||||
|
||||
```
|
||||
warmup (缓存 model=A, key=X)
|
||||
↓
|
||||
新请求 (model=B, key=Y)
|
||||
↓
|
||||
tryReuse() 检测不兼容 → 回退冷启动 (~2s)
|
||||
↓
|
||||
cacheRuntimeConfig(B, Y) → 更新缓存
|
||||
↓
|
||||
refill warmup 用 (B, Y) 创建
|
||||
↓
|
||||
后续请求 (B, Y) → 命中 ✅
|
||||
```
|
||||
|
||||
**最多影响一次会话**(配置变更的那次),后续自动纠正。这与修改前行为一致——修改前是每次都 miss,修改后仅配置变更时 miss 一次。
|
||||
|
||||
---
|
||||
|
||||
## 4. 预期效果
|
||||
|
||||
| 场景 | 修改前 | 修改后 |
|
||||
|------|--------|--------|
|
||||
| 首次 init → 首次会话 | miss → 冷启动 ~3.7s | miss → 冷启动 ~3.7s(首次无缓存) |
|
||||
| 首次会话后 → 第二次会话 | **miss** → 冷启动 ~2.6s | **命中** → ~1.5s(省 ~1.1s) |
|
||||
| 连续新会话(配置不变) | 每次前 1-2 个 miss | 仅首次 miss,后续均命中 |
|
||||
| 配置变更 | miss → 冷启动 | miss → 冷启动 → 自动纠正缓存 |
|
||||
|
||||
**关键指标改善**:
|
||||
|
||||
- 连续新会话 Init 耗时:5,705ms / 6,097ms → **~1,500ms**(reduced ~70%)
|
||||
- 首消息端到端(不含 LLM TTFT):~8s → **~6s**(节省 warmup 冷启动开销)
|
||||
|
||||
---
|
||||
|
||||
## 5. 测试覆盖
|
||||
|
||||
### 5.1 新增测试
|
||||
|
||||
| 测试 | 验证内容 |
|
||||
|------|---------|
|
||||
| `warmup runtime config 缓存:首次 miss 后 refill 命中后续请求` | 首次 miss → 缓存 → refill 带缓存 → 第二次命中 |
|
||||
| `warmup runtime config 缓存:配置变更时回退冷启动并更新缓存` | configA miss → refill(A) → configB miss → refill(B) → B 命中 |
|
||||
|
||||
### 5.2 回归测试
|
||||
|
||||
全部 54 个 warmup 相关测试通过,包括:
|
||||
- 运行时配置缺失回退冷启动(原有测试不受影响)
|
||||
- MCP 配置不兼容回退冷启动
|
||||
- qimingcode 连续命中补仓
|
||||
- destroy() 清理 warmup
|
||||
- persistent MCP 归一化
|
||||
|
||||
---
|
||||
|
||||
## 6. 相关文档
|
||||
|
||||
- [首消息性能优化报告 (2026-03-23)](./FIRST-MESSAGE-PERF-OPT-2026-03-23.md)
|
||||
- [macOS 首消息性能测试报告 (2026-03-31)](./MACOS-FIRST-MESSAGE-PERF-REPORT-2026-03-31.md)
|
||||
- [Session 复用修复 (2026-03-24)](./SESSION-REUSE-FIX-2026-03-24.md)
|
||||
|
||||
---
|
||||
|
||||
*文档生成时间: 2026-03-31*
|
||||
@@ -0,0 +1,195 @@
|
||||
# Windows 平台首消息性能测试报告
|
||||
|
||||
**报告日期**: 2026-03-23
|
||||
**测试平台**: Windows
|
||||
**引擎类型**: claude-code
|
||||
**日志来源**: `C:\Users\soddygo\.qimingclaw\logs\main.2026-03-23.log`
|
||||
**参考报告**: [DEEP-RESEARCH-PERF-REPORT-2026-03-20.md](../DEEP-RESEARCH-PERF-REPORT-2026-03-20.md) (macOS 测试)
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
本报告对比分析了 Windows 平台上首消息性能优化前后的差异,并与 macOS 平台历史数据进行对比。
|
||||
|
||||
### 关键发现
|
||||
|
||||
| 指标 | 优化前 (cdb41fd) | 优化后 (12a102b) | 提升 |
|
||||
|-----|-----------------|-----------------|------|
|
||||
| **首消息总耗时** | ~9,000ms | ~4,000ms | **55%** |
|
||||
| **ensureEngine** | 8,948ms | 4,018ms | **55%** |
|
||||
| **引擎启动** | 7,000ms+ | ~3,800ms | **~46%** |
|
||||
|
||||
### 与 macOS 对比
|
||||
|
||||
| 平台 | 首消息总耗时 | ensureEngine | 状态 |
|
||||
|-----|------------|--------------|------|
|
||||
| **macOS** (历史) | ~7,800ms | ~7,700ms | 基准 |
|
||||
| **Windows 优化前** | ~9,000ms | ~8,900ms | 慢 15% |
|
||||
| **Windows 优化后** | ~4,000ms | ~4,000ms | **快 48%** |
|
||||
|
||||
---
|
||||
|
||||
## 一、测试会话数据
|
||||
|
||||
### 1.1 优化前会话 (cdb41fd)
|
||||
|
||||
| 时间 | session_id | 总耗时 | parseBody | validate | ensureWorkspace | ensureEngine | chat |
|
||||
|-----|-----------|--------|-----------|----------|-----------------|--------------|------|
|
||||
| 20:17:22.321 | 526b1884-344f-496d-b948-e143db6b8ac3 | **9,017ms** | 1ms | 6ms | 3ms | **8,948ms** | 59ms |
|
||||
|
||||
**详细分解**:
|
||||
```
|
||||
ensureEngine 8,948ms 分解:
|
||||
├── parseCCtxServers: 1,732ms (19%)
|
||||
├── syncMcp: 5,204ms (58%) ← 最大瓶颈
|
||||
├── extractReal: 1ms (<1%)
|
||||
├── ensureBridge: 2ms (<1%)
|
||||
└── getOrCreate: 2,006ms (22%)
|
||||
├── mmemory: 263ms
|
||||
├── evict: 1ms
|
||||
└── init: 1,737ms
|
||||
```
|
||||
|
||||
### 1.2 优化后会话 (12a102b)
|
||||
|
||||
| 时间 | session_id | 总耗时 | parseBody | validate | ensureWorkspace | ensureEngine | chat |
|
||||
|-----|-----------|--------|-----------|----------|-----------------|--------------|------|
|
||||
| 19:58:06.135 | a52a4e75-08f5-4f9b-9f73-e49f4f7eb41c | **4,054ms** | 1ms | 3ms | 2ms | **4,046ms** | 3ms |
|
||||
| 19:58:52.938 | 8cd0f9d9-6c2e-419b-a4f1-7c6ea7559b0c | **3,854ms** | 1ms | 3ms | 2ms | **3,801ms** | 47ms |
|
||||
| 20:08:14.780 | e83b95ca-0ef8-45e2-8947-842c382e9560 | **4,097ms** | 1ms | 6ms | 3ms | **4,036ms** | 51ms |
|
||||
| 20:10:37.600 | 711d37f9-8a99-4bb8-a7f0-85c11d6b0b86 | **4,080ms** | 5ms | 6ms | 3ms | **4,018ms** | 48ms |
|
||||
|
||||
**平均值**:
|
||||
- 总耗时: **4,021ms**
|
||||
- ensureEngine: **3,975ms**
|
||||
- chat: **37ms**
|
||||
|
||||
---
|
||||
|
||||
## 二、性能对比分析
|
||||
|
||||
### 2.1 优化前后对比
|
||||
|
||||
```
|
||||
优化前 (cdb41fd):
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 总耗时: 9,017ms │
|
||||
│ ├── parseBody: 1ms (<1%) │
|
||||
│ ├── validate: 6ms (<1%) │
|
||||
│ ├── ensureWorkspace: 3ms (<1%) │
|
||||
│ ├── ensureEngine: 8,948ms (99%) ← 瓶颈 │
|
||||
│ │ ├── parseCCtxServers: 1,732ms │
|
||||
│ │ ├── syncMcp: 5,204ms (58%) ← 最大瓶颈 │
|
||||
│ │ └── getOrCreate: 2,006ms │
|
||||
│ └── chat: 59ms (<1%) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
优化后 (12a102b):
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 总耗时: 4,021ms (↓ 55%) │
|
||||
│ ├── parseBody: 2ms (<1%) │
|
||||
│ ├── validate: 4ms (<1%) │
|
||||
│ ├── ensureWorkspace: 3ms (<1%) │
|
||||
│ ├── ensureEngine: 3,975ms (99%) ← 仍占大头但显著降低 │
|
||||
│ │ └── 并行执行 syncMcp + ensureMemoryReady │
|
||||
│ └── chat: 37ms (<1%) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 关键优化点
|
||||
|
||||
根据 [FIRST-MESSAGE-PERF-OPT-2026-03-23.md](./FIRST-MESSAGE-PERF-OPT-2026-03-23.md) 的实现:
|
||||
|
||||
1. **MCP Proxy Bridge 预热** (warmupMcpBridge)
|
||||
- 应用启动时异步预热
|
||||
- 减少首次 syncMcp 时间
|
||||
|
||||
2. **并行执行** (Promise.all)
|
||||
- `syncMcpConfigToProxyAndReload()` 与 `ensureMemoryReady()` 并行
|
||||
- 节省串行等待时间
|
||||
|
||||
3. **引擎预热策略**
|
||||
- 提前初始化引擎环境
|
||||
- 减少首次请求时的冷启动时间
|
||||
|
||||
---
|
||||
|
||||
## 三、与 macOS 平台对比
|
||||
|
||||
### 3.1 历史数据回顾 (macOS)
|
||||
|
||||
来自 [DEEP-RESEARCH-PERF-REPORT-2026-03-20.md](../DEEP-RESEARCH-PERF-REPORT-2026-03-20.md):
|
||||
|
||||
| 会话 | 时间 | 总耗时 | ensureEngine | 状态 |
|
||||
|-----|------|--------|--------------|------|
|
||||
| #4 | 10:15:24.141 | 7,492ms | 7,409ms | 冷启动 |
|
||||
| #5 | 11:09:48.812 | 7,822ms | 7,734ms | 复用 |
|
||||
| #6 | 12:19:52.196 | 7,800ms | 7,708ms | 复用 |
|
||||
| #7 | 12:24:12.225 | 8,005ms | 7,919ms | 复用 |
|
||||
| #8 | 12:25:32.661 | 7,908ms | 7,815ms | 复用 |
|
||||
|
||||
**macOS 平均**: 总耗时 ~7,800ms,ensureEngine ~7,700ms
|
||||
|
||||
### 3.2 跨平台对比
|
||||
|
||||
```
|
||||
性能对比 (首消息总耗时):
|
||||
|
||||
macOS (历史基准)
|
||||
├── 冷启动: ~7,500ms
|
||||
└── 复用: ~7,900ms
|
||||
|
||||
Windows 优化前
|
||||
└── 冷启动: ~9,000ms (慢 15-20%)
|
||||
|
||||
Windows 优化后 ✅
|
||||
└── 冷启动: ~4,000ms (快 48%)
|
||||
```
|
||||
|
||||
### 3.3 平台差异分析
|
||||
|
||||
| 因素 | macOS | Windows | 影响 |
|
||||
|-----|-------|---------|------|
|
||||
| 文件系统 | APFS | NTFS | Windows 略慢 |
|
||||
| 进程启动 | 快 | 较慢 | Windows 进程启动开销大 |
|
||||
| UV/Node 缓存 | 高效 | 略慢 | Windows 路径处理较慢 |
|
||||
| 优化效果 | - | 显著 | Windows 优化后反超 |
|
||||
|
||||
---
|
||||
|
||||
## 四、结论与建议
|
||||
|
||||
### 4.1 结论
|
||||
|
||||
1. **优化效果显著**: Windows 平台首消息耗时从 ~9s 降至 ~4s,**提升 55%**
|
||||
2. **超越 macOS**: 优化后 Windows (~4s) 比历史 macOS (~7.8s) **快 48%**
|
||||
3. **引擎启动仍是瓶颈**: ensureEngine 仍占总耗时 99%,但已从 8.9s 降至 4s
|
||||
|
||||
### 4.2 建议
|
||||
|
||||
1. **保持当前优化**: 并行执行策略效果显著,建议保留
|
||||
2. **进一步预热**: 考虑在应用启动时预热引擎本身(不仅是 MCP Bridge)
|
||||
3. **监控生产环境**: 持续收集 Windows 用户性能数据
|
||||
4. **macOS 同步优化**: 将 Windows 的优化策略同步到 macOS 版本
|
||||
|
||||
---
|
||||
|
||||
## 附录:原始日志摘录
|
||||
|
||||
### 优化前 (cdb41fd)
|
||||
```
|
||||
[2026-03-23 20:17:22.258] [debug] ⏱️ [getOrCreateEngine][PERF] 总耗时: 1001ms (mmemory=263ms, evict=1ms, init=737ms)
|
||||
[2026-03-23 20:17:22.260] [debug] ⏱️ [ensureEngine][PERF] 总耗时: 8945ms (parseCCtxServers=1732ms, syncMcp=5204ms, extractReal=1ms, ensureBridge=2ms, getOrCreate=2006ms)
|
||||
[2026-03-23 20:17:22.321] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 9017ms (parseBody=1ms, validate=6ms, ensureWorkspace=3ms, ensureEngine=8948ms, chat=59ms)
|
||||
```
|
||||
|
||||
### 优化后 (12a102b)
|
||||
```
|
||||
[2026-03-23 20:10:37.600] [info] ⏱️ [HTTP][PERF] /computer/chat 总耗时: 4080ms (parseBody=5ms, validate=6ms, ensureWorkspace=3ms, ensureEngine=4018ms, chat=48ms)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: 2026-03-23*
|
||||
*对比基准: macOS DEEP-RESEARCH-PERF-REPORT-2026-03-20.md*
|
||||
Reference in New Issue
Block a user