2026-10-21 对 ec7d3d1 使用下面同一份真实 Vue / IndexedDB 基准,在同一台机器、同样的 4 倍 CPU 降速下各运行三轮。评分撤销步骤只保存本次记录与卡片的标识,不复制整库或遍历全部记录;保存成功后才加入历史。
| 卡片 / 历史 | 评分到下一题:0.26.0 → 0.27.0 | 重载至首页:0.26.0 → 0.27.0 |
|---|---|---|
| 1,000 张 / 10,000 条 | 51.2 ms → 47.8 ms | 259.1 ms → 261.5 ms |
| 10,000 张 / 100,000 条 | 230.7 ms → 232.5 ms | 1372.9 ms → 1310.2 ms |
数值为三轮中位数;0.26.0 使用下文保存的历史记录,未重新跑对照。测量未出现明显评分回退,不能据此判断微小差异代表提升。全部样本与环境见 0.27.0 原始数据。这项基准不包含网络、首次下载或后端往返,也不覆盖任意复杂 HTML 的排版成本。
对照为 3e52bfe 加同一份复习基准,优化后为 ee00645。测试没有重跑 0.6.0,不能据此计算旧版在用户设备上的改善倍数。
npm run benchmark -- --review --cards 1000 --runs 3
npm run benchmark -- --review --cards 10000 --runs 3基准挂载真实 Vue 应用,使用 IndexedDB 保存并重载卡片和历史,然后交替点击 8 次「重来 / 良好」。计时从点击评分到下一题出现并等待两帧,包含持久保存、组件更新和绘制。每轮使用独立 Chromium 上下文;数据库名虽与应用相同,但不访问日常浏览器或桌面数据目录。CPU 固定降速 4 倍,不同时运行其他本地验证任务。
2026-10-20,同一台 Linux / AMD RYZEN AI MAX+ 395,Node 24.18.0、Chromium 156.0.8078.4。以下为三轮的中位数,所有样本与环境见原始数据。
| 卡片 / 历史 | 评分到下一题:优化前 → 后 | 重载至首页:优化前 → 后 |
|---|---|---|
| 1,000 张 / 10,000 条 | 71.4 ms → 51.2 ms | 248.7 ms → 259.1 ms |
| 10,000 张 / 100,000 条 | 372.1 ms → 230.7 ms | 1443.1 ms → 1372.9 ms |
主要修改:复用未变化的题面,单次渲染复用队列数据;计算每日额度时不再生成全部题面或逐条重算日期;增量检查追加的评分;快照列表在评分成功后后台读取。仍然等待事务成功再切题,失败保留当前答案和重试入口。后台响应检查库身份和请求顺序。
这份基准包含新增的历史显示与设置代码,衡量本机可复现的响应,不承诺所有设备无卡顿。它不包含首次下载、字体加载、真实后端往返或系统磁盘差异;4 倍 CPU 降速也不能直接换算成某款设备。启动仍需读取结构化数据,更多笔记和历史仍会增加启动成本;媒体和提交代码按需读取。
npm run benchmark -- --history --runs 3 在独立 Chromium 上下文中建立 10,000 张卡、100,000 条复习记录、20,000 次练习和 60,000 次提交。每份代码 2,048 字符,每题含约 2 KB 的原始题面。数据只写入随机命名的临时 IndexedDB,完成后删除。
每轮先造数并保存,随后重载页面,释放造数阶段的对象,再测重新读取、历史视图、筛选、展开代码、提交状态保存、评分和备份。输出包含每轮数据、数值中位数、CPU、系统、Node 与浏览器版本。可用 --output /tmp/history.json 指定结果位置,默认写入 test-results/history-benchmark.json。
loadMs 从读取数据库计时到建立内存索引,包含自动快照检查;它不包含下载应用、启动浏览器或加载字体。loadedHeapMiB 在读取后、挂载历史视图前主动回收垃圾再取 Chromium 的 JS 堆使用量;它不代表进程总内存,也不能直接用于推断 WebKit 或系统安装包的内存。
历史视图挂载和筛选耗时包含 Vue 更新与两帧绘制等待。导出写入流式接收器,包含读取、序列化与 ZIP 压缩,不包含系统保存对话框或磁盘写入。代码使用重复文本,因此压缩率与耗时只适合比较同一份基准。
2026-10-18,Linux 7.0.0-34-generic,AMD RYZEN AI MAX+ 395,Node 24.18.0,Chromium 156.0.8078.4。对照代码为 71baa89(0.8.2 加基准脚本,尚未改动存储),优化代码为 ae5961e,两者使用同一份重载测量脚本。下面列三轮中位数,所有样本见原始结果。
| 项目 | 0.8.2 | 0.8.3 |
|---|---|---|
| 读取学习库 | 1,095 ms | 910 ms |
| 读取后 JS 堆 | 259 MiB | 143 MiB |
| 首次挂载历史 | 122 ms | 143 ms |
| 筛选历史 | 30 ms | 44 ms |
| 展开提交代码 | 34 ms | 34 ms |
| 保存提交意图 | 306 ms | 60 ms |
| 保存正式编号 | 266 ms | 51 ms |
| 保存判题结果 | 259 ms | 54 ms |
| 确认复习评分 | 285 ms | 58 ms |
| 初次批量保存 | 2,640 ms | 3,481 ms |
导出完整 .repeaty |
1,804 ms | 2,659 ms |
| 启动时载入的代码字符 | 122,880,000 | 0 |
| 折叠历史中的正文节点 | 100 | 0 |
优化后三轮的 JS 堆采样为 139–143 MiB,本文采用中位数并保留全部原始样本。历史视图在基准页单独挂载,挂载与筛选耗时不代表整页导航。
这是本机测量,不能当作低配设备的性能保证。初次批量保存会额外维护摘要索引;导出则分批取回完整代码,交换的是平时的内存占用与导入、导出时的工作量。自动快照仍使用修订号和变更日志,不复制全库。
另用原有的普通卡基准补测一次:1 万张卡、10 万条复习记录,评分总耗时为 29.4 → 25.1 ms。它只用于检查基础评分路径,单轮结果不作为性能保证;原始值同样保留在结果文件中。
IndexedDB 从 v6 升为 v7,新增 attemptSummaries 派生索引,原始提交仍在 attempts。首次升级需要扫描既有提交建立摘要;升级事务完成前不切换新库。提交、摘要与修订号一起提交或回滚,删除和恢复快照也同时维护两处记录。
运行时 Library.attempts 可以是 AttemptRecord 摘要,完整提交由 getAttempt 读取。读取检查修订号与记录身份,组件卸载、切换记录或收起时丢弃正文;读取失败可以重试。查看答案状态只在正文读取成功后更新。
API v3 增加可选 historyVersion: 1 能力。支持的服务提供 GET /library/summary 与 POST /library/attempts,后者按编号或位置读取完整记录。两者沿用账户与 X-Repeaty-User 校验;正文还必须匹配请求中的库修订号。批量读取最多 128 条,服务端按约 4 MiB 原始 JSON 限制批次。本地同样按 128 条读取。旧 API v3 服务继续通过原接口读取完整库。
学习数据仍为 v5、SQLite schema 为 v2、.repeaty 容器为 v2。备份不保存摘要代替正文:流式导出会核对每批的修订号、顺序和数量,正文不完整或库发生变化时中止。旧 JSON 导出和快照恢复按需读入完整记录,仍受原有容量限制。
启动仍读取笔记题面、练习快照、调度状态和提交摘要,搜索与历史分页使用这些内存索引。SQLite 的摘要查询也仍需投影原记录。本轮按需读取的范围是提交代码与裁判详情;更多题面、历史或账户数据仍可能增加启动成本。
本基准没有媒体,不测网络延迟、三平台安装包启动时间或 Today 查询 P95。媒体和长文本使用独立的 128 MiB 浏览器往返测试;快照、旧库升级、完整正文导出、账户隔离与读取失败另有回归测试。