# Milestone v1.0: Performance Optimization

**Status:** ✅ SHIPPED 2026-04-26
**Phases:** 1–5
**Total Plans:** 10

## Overview

dm-database-parser-sqllog 性能优化里程碑。在现有内存映射零拷贝架构基础上，通过基准测量基础设施、正确性加固、热路径微优化、核心算法重写和并行索引架构，将单线程解析吞吐提升 35.5%（8.67 GiB/s），并引入两阶段并行 RecordIndex API。

## Phases

### Phase 1: Measurement

**Goal**: 开发者可以用真实语料库衡量任意代码改动对吞吐量的影响，并在 CI 中自动捕获退化
**Depends on**: Nothing (first phase)
**Plans**: 2 plans

Plans:
- [x] 01-01-PLAN.md — 扩展 benchmark 变体（MEAS-01/02/03）：多行语料库 + Throughput 双单位 + metrics 变体
- [x] 01-02-PLAN.md — CI 回归门禁基础设施（MEAS-04）：check-regression.sh + benchmark.yml 门禁 + update-baseline.yml

**Details:**
- 新增 `generate_synthetic_log_multiline` 函数（20% 多行记录）
- criterion `Throughput::Bytes` + `Throughput::Elements` 双维度测量
- `parse_sqllog_metrics_5mb` 覆盖 `parse_performance_metrics()` 热路径
- CI 回归门禁：`check-regression.sh` 对比 `baseline.json`，退化 >5% 则 fail

### Phase 2: Correctness

**Goal**: 消除 unsafe 解码路径的已知正确性风险，使后续任意热路径改动不会踩到未定义行为
**Depends on**: Phase 1
**Plans**: 2 plans

Plans:
- [x] 02-01-PLAN.md — 代码修复（CORR-01/03）：全文件编码检测 + find_indicators_split 验证守卫 + 6 条新测试
- [x] 02-02-PLAN.md — Miri CI 基础设施（CORR-02）：miri.yml 作业 + 五个测试文件 cfg 标注

**Details:**
- CORR-01: 编码检测从仅采样 64 KB 扩展至全文件 head+tail 采样，消除大文件 GB18030 误判
- CORR-03: `find_indicators_split` 增加验证守卫，SQL body 内含指标关键字时正确处理
- CORR-02: Miri CI 覆盖 unsafe 解码路径，无内存安全报错

### Phase 3: HotPath

**Goal**: 通过低风险的内联提示、早退逻辑和 mmap 建议，消除热路径中的无谓开销
**Depends on**: Phase 2
**Plans**: 2 plans

Plans:
- [x] 03-01-PLAN.md — HOT-01/02：find_indicators_split 早退逻辑 + 单次 memrchr 反向扫描
- [x] 03-02-PLAN.md — HOT-03/04：parse_performance_metrics inline(always) + cold 错误路径 + mmap advise(Sequential)

**Details:**
- HOT-01: 记录末尾不含 `.` 时 O(1) 早退，跳过 3 次 rfind
- HOT-02: 单次 `memrchr(b':')` 反向扫描替代 3 个独立 SIMD FinderRev
- HOT-03: `#[inline(always)]` 热路径 + `#[cold]` 错误路径标注
- HOT-04: `mmap.advise(Advice::Sequential)` 顺序读取建议

### Phase 4: CoreAlgo

**Goal**: 重写记录边界检测的核心扫描算法，实现预期 15–45% 的单线程吞吐提升
**Depends on**: Phase 3
**Plans**: 1 plan

Plans:
- [x] 04-01-PLAN.md — CoreAlgo 算法重写（ALGO-01/02）：FINDER_RECORD_START + is_timestamp_start u64 掩码 + LogIterator::next() 混合快速路径

**Details:**
- ALGO-01: `FINDER_RECORD_START: LazyLock<Finder<'static>>` 搜索 `b"\n20"` 替代逐行 memchr 循环
- ALGO-02: `is_timestamp_start()` 使用两次 LE u64 load + 位掩码替代 8 个独立字节比较
- 混合策略：单行记录走 memchr 快速路径（O(record)），多行走 memmem find_iter（SIMD 跳跃）
- **实测结果：+35.5% 单线程吞吐（8.67 GiB/s）**，远超 ≥10% 门禁

### Phase 5: Parallel

**Goal**: 通过两阶段索引扫描实现记录级均匀并行分区，并在小文件场景避免 Rayon 开销负收益
**Depends on**: Phase 4
**Plans**: 3 plans

Plans:
- [x] 05-01-PLAN.md — RecordIndex 类型 + LogParser::index() 公共方法（PAR-01）+ 3 个新单元测试
- [x] 05-02-PLAN.md — 重写 par_iter()：32 MB 阈值小文件单分区 + 大文件两阶段索引分区（PAR-02/PAR-03）+ 3 个新测试
- [x] 05-03-PLAN.md — 64 MB seq/par benchmark 对 + PAR-02 speedup 人工验证

**Details:**
- PAR-01: `pub struct RecordIndex` + `LogParser::index()` 单线程全文扫描，返回记录字节偏移列表
- PAR-02/PAR-03: `par_iter()` 改用 RecordIndex 实现记录级均匀分区；文件 <32 MB 自动退化为串行
- **实测 speedup：1.01x（远低于 1.6x 目标）**
- 根本原因：Amdahl 定律。Phase 1（顺序 index() 扫描）主导端到端时间，Phase 2（并行解析）计算量极轻（~206 字节/记录），水平扩展无法突破串行瓶颈。8.4 GiB/s 为单核利用上限。
- **决策：accept-as-is**，两阶段架构和 PAR-01/PAR-03 实现均符合要求

---

## Milestone Summary

**Key Decisions:**

| Decision | Rationale | Outcome |
|----------|-----------|---------|
| Phase 顺序：Measurement → Correctness → HotPath → CoreAlgo → Parallel | 先建立可信测量，再修正确性风险，再优化，保证每步可验证 | ✓ 有效 |
| CORR-01: head+tail 采样替代仅 64 KB | simdutf8 ~50 GB/s，one-time 开销可接受，消除大文件 GB18030 UB | ✓ 有效 |
| Phase 4 混合快速路径（偏离纯 memmem 计划）| 纯 find_iter 实测 -35% 退化；单行记录（占绝大多数）需 memchr 快速路径 | ✓ 关键决策 |
| Phase 5 accept-as-is（PAR-02 speedup 1.01x）| Amdahl 定律：index() 串行扫描主导，par 解析几乎无收益 | ✓ 有据可查 |

**Issues Resolved:**
- Phase 2: Cow::Owned 修复消除 unsafe 生命周期延长
- Phase 2: LogIterator::next 改为迭代循环防止大量空行栈溢出
- Phase 4: 纯 memmem 方案实测退化 35%，混合策略解决

**Issues Deferred:**
- PAR-02 speedup ≥1.6x 目标未达成（Known Gap）

**Technical Debt:**
- 无重大技术债务
- PAR-02 speedup 目标未达：若需多线程加速，需重新设计工作负载（GPU 卸载、减少每记录工作量、或换 CPU-bound 工作）

---

*Archive created: 2026-04-26*
*For current project status, see .planning/ROADMAP.md*
