性能优化与评审
2025/11/16大约 4 分钟性能维护Profiling内存回归验证
性能优化与评审
密码实现优化必须保持算法和协议语义。项目采用“正确性基线、性能剖析、小范围修改、差分验证、同机基准”的顺序,不接受仅凭代码行数或单次计时声称提升。
当前实现选择
- SM2 KDF 复用计数器输入缓冲区,并检测全零派生结果。
- TypeScript
SM3类维护真实增量状态,不缓存完整消息。 - SM4/ZUC bytes API 避免明文经过 UTF-8 往返。
- SM2 曲线运算使用
@noble/curves,SHA/HMAC-SHA 使用@noble/hashes。 - ESM、CJS 和 IIFE 从同一公共入口构建,避免不同产物维护不同实现。
这些是实现事实,不代表在所有 JavaScript 引擎上具有固定提升比例。
评审流程
- 用完整单测、标准向量和 parity 建立正确性基线。
- 用 CPU profile 和 allocation profile 定位热点,记录输入与调用参数。
- 每次只改变一个可解释因素,避免把协议调整和性能调整混在一起。
- 对确定性结果做向量比较,对随机算法做往返、验签和篡改拒绝。
- 在同机交替运行前后版本,保留原始输出和失败结果。
- 检查包体积、内存分配、错误语义及浏览器主线程影响。
数据和内存
- 已有二进制输入应保持
Uint8Array,避免反复转 hex/base64。 - 大文件摘要使用增量
SM3/SHA*类。分组和流密码是否可分块取决于 mode 状态,不能对每个分片重复调用一次性 API。 - Worker 适合隔离长 CPU 任务;优先转移所有权而非复制大缓冲区,并限制密钥副本数量。
Uint8Array.fill(0)只能覆盖当前缓冲区,不能保证清除字符串、JIT 临时值和历史复制。- 缓存扩展密钥或状态会延长敏感材料生命周期,必须与吞吐收益一起评审。
格式取舍
压缩 SM2 公钥为 33 字节,非压缩公钥为 65 字节。压缩格式减少传输大小,但接收端需要恢复曲线点;应按协议带宽和实测解析成本选择。
raw SM2 签名固定 64 字节,DER 长度可变。跨 Java/JCA 系统时 DER 更常见,但格式选择首先由互操作协议决定,不能只按字节数决定。
提交证据
性能相关 PR 应包含:
- 基准环境、commit 和工作区状态;
- 前后完整输出及重复次数;
- profile 证据和目标热点;
- 标准向量、负向测试和 parity 结果;
- 分配、包体积及协议字段是否变化;
- 对浏览器代码的主线程响应性检查。
缺少这些证据时,应把改动描述为“实现调整”,不能对外声称性能提升。