Repository navigation
v1.9.0 · 性能:打开表格快 1483 倍 · 清理 757 MB
性能(实测,不是估的)
先加了性能基线测试(perf_baseline_page_and_search,#[ignore] 手动跑),
因为它要插 10 万行、进 CI 会让每次提交都变慢;但必须能手动跑 ——
性能数字不能靠感觉,也不能靠回忆。
优化前(本机实测):
| 规模 | 插入 | 首页 | 游标页 | 筛选 |
|---|---|---|---|---|
| 1 万行 | 168ms | 28.4ms | 26.3ms | 27.5ms |
| 10 万行 | 1.81s | 336ms | 329ms | 331ms |
病根(查出来的,不是猜的):store::scan 会把整表克隆出来 ——
每行一个 key 的 String 加一个 value 的 String,然后逐行 JSON 反序列化。
而最常见的查询是"打开表格看第一页":为了显示 50 行,去克隆 10 万个 String。
三个指标数字几乎一样,正是"卡在同一个地方"的证据。
改法:加 store::scan_take(prefix, n)(只取前 n 条),
在 page_rows_filtered 里加一条快路径 —— 无筛选、无游标、按 rowid 升序时直接取前若干行。
这条快路径能成立,靠的是一个已存在的事实:记录 key 是
rec/<表>/<20 位补零 rowid>,所以 BTreeMap 的字典序就是 rowid 升序。
补零是关键 —— 换成不补零的数字串,10 会排在 9 前面,这条快路径就不成立了。
优化后:
| 规模 | 首页 | 变化 |
|---|---|---|
| 1 万行 | 28.4ms → 0.31ms | 快 93 倍 |
| 10 万行 | 336ms → 0.23ms | 快 1483 倍 |
还没优化的(如实说):游标页与筛选仍是 ~330ms。
它们必须看全部行(游标要定位、筛选要逐行比),不是"也能顺手改掉"的东西 ——
要做需要倒排索引或增量扫描,是另一个量级的工程。
过程中被测试抓到一个我引入的 bug:快路径起初只取 limit 行,
而 finish_page 靠"多出来的那一行"判断 has_more,于是"还有 50 行没取"却报 has_more=false。
分页测试当场失败。改成取 limit + 1 行。
(这件事的意义:改动查询逻辑时,旧测试是最好的保险 —— 它比我先发现问题。)
清理
仓库瘦身 757 MB(23 项):
| 内容 | 处理 |
|---|---|
poc/*/node_modules target-msvc(约 700 MB) |
删缓存,源码保留(AGENTS 明确:缓存可删、源码不要删) |
dist/ 旧版本 zip(31 个) |
删,保留最近 3 个;GitHub Release 里都有 |
local-docs/runs/ 旧走查目录 |
删,保留最近 5 个 |
体检结论(顺带做的)
| 项 | 结果 |
|---|---|
| 编译警告 | 0 条 |
#[allow(dead_code)] |
5 处(都是有理由的) |
| 前端函数跨文件重名 | 17 组,但全部是 IIFE 独立作用域,不构成问题 |
| 最大文件 | main.rs 4480 行(主要是 dispatch 的巨型 match) |
关于
main.rs要不要拆:暂时不拆。那个 match 是check-wiring门禁的
识别形式,拆它有真实风险而收益只是"文件数字好看一点"。不做没有把握的重构。
验证
单元 265 通过 / 0 失败 · 烟测 112/112 · 门禁五道 ·
性能数字为本机实测(cargo test perf_baseline -- --ignored --nocapture)
[1.9.0] - 2026-09-26 · 性能:打开表格快 1483 倍 · 仓库清理 757 MB
性能(实测,不是估的)
先加了性能基线测试(perf_baseline_page_and_search,#[ignore] 手动跑),
因为它要插 10 万行、进 CI 会让每次提交都变慢;但必须能手动跑 ——
性能数字不能靠感觉,也不能靠回忆。
优化前(本机实测):
| 规模 | 插入 | 首页 | 游标页 | 筛选 |
|---|---|---|---|---|
| 1 万行 | 168ms | 28.4ms | 26.3ms | 27.5ms |
| 10 万行 | 1.81s | 336ms | 329ms | 331ms |
病根(查出来的,不是猜的):store::scan 会把整表克隆出来 ——
每行一个 key 的 String 加一个 value 的 String,然后逐行 JSON 反序列化。
而最常见的查询是"打开表格看第一页":为了显示 50 行,去克隆 10 万个 String。
三个指标数字几乎一样,正是"卡在同一个地方"的证据。
改法:加 store::scan_take(prefix, n)(只取前 n 条),
在 page_rows_filtered 里加一条快路径 —— 无筛选、无游标、按 rowid 升序时直接取前若干行。
这条快路径能成立,靠的是一个已存在的事实:记录 key 是
rec/<表>/<20 位补零 rowid>,所以 BTreeMap 的字典序就是 rowid 升序。
补零是关键 —— 换成不补零的数字串,10 会排在 9 前面,这条快路径就不成立了。
优化后:
| 规模 | 首页 | 变化 |
|---|---|---|
| 1 万行 | 28.4ms → 0.31ms | 快 93 倍 |
| 10 万行 | 336ms → 0.23ms | 快 1483 倍 |
还没优化的(如实说):游标页与筛选仍是 ~330ms。
它们必须看全部行(游标要定位、筛选要逐行比),不是"也能顺手改掉"的东西 ——
要做需要倒排索引或增量扫描,是另一个量级的工程。
过程中被测试抓到一个我引入的 bug:快路径起初只取 limit 行,
而 finish_page 靠"多出来的那一行"判断 has_more,于是"还有 50 行没取"却报 has_more=false。
分页测试当场失败。改成取 limit + 1 行。
(这件事的意义:改动查询逻辑时,旧测试是最好的保险 —— 它比我先发现问题。)
清理
仓库瘦身 757 MB(23 项):
| 内容 | 处理 |
|---|---|
poc/*/node_modules target-msvc(约 700 MB) |
删缓存,源码保留(AGENTS 明确:缓存可删、源码不要删) |
dist/ 旧版本 zip(31 个) |
删,保留最近 3 个;GitHub Release 里都有 |
local-docs/runs/ 旧走查目录 |
删,保留最近 5 个 |
体检结论(顺带做的)
| 项 | 结果 |
|---|---|
| 编译警告 | 0 条 |
#[allow(dead_code)] |
5 处(都是有理由的) |
| 前端函数跨文件重名 | 17 组,但全部是 IIFE 独立作用域,不构成问题 |
| 最大文件 | main.rs 4480 行(主要是 dispatch 的巨型 match) |
关于
main.rs要不要拆:暂时不拆。那个 match 是check-wiring门禁的
识别形式,拆它有真实风险而收益只是"文件数字好看一点"。不做没有把握的重构。
验证
单元 265 通过 / 0 失败 · 烟测 112/112 · 门禁五道 ·
性能数字为本机实测(cargo test perf_baseline -- --ignored --nocapture)