
什么是性能基准测试?
性能基准测试通过测量代码执行速度来比较实现方案、识别瓶颈并指导优化决策。基准测试会重复运行代码,并报告执行时间的统计指标。

为什么要进行代码基准测试?
微基准测试可以帮助你:
- 比较算法实现:在你的用例中,快速排序还是归并排序更快?
- 选择库函数:对于你的数据规模,
Array.map()还是for循环更快? - 验证优化效果:你的“优化”是否真的提升了性能?
- 了解扩展性:性能如何随数据规模增长而变化?
- 设定性能预算:记录预期的性能特征
基准测试的设置-测试-清理模式
一个结构良好的基准测试包含三个阶段:
// 设置:准备数据和状态(不计入测量)
const data = generateLargeArray(10000);
// 测试:被测量的代码(多次运行)
function testCase() {
return data.filter(x => x > 500).map(x => x * 2);
}
// 清理:资源释放(不计入测量)
data = null;
设置阶段确保基准测试只测量相关代码,而不包括初始化开销。
统计考量
为什么要运行多次迭代?
单次测量毫无意义——JavaScript 引擎会变化、垃圾回收会暂停、操作系统调度会中断执行。运行数千次迭代并计算统计量才能得到可靠结果。
关键统计指标
- 均值:所有运行的平均执行时间
- 中位数:中间值——受异常值影响小于均值
- 标准差:衡量变异性——低标准差意味着结果一致
- 最小值/最大值:观察到的最快和最慢运行
- 每秒操作数(ops/sec):函数每秒能运行多少次
误差范围
如果一个基准测试显示“函数 A:1.2M ops/sec ± 3%”,意味着真实值很可能在 1.164M 到 1.236M ops/sec 之间。如果两个函数的范围重叠,则它们在统计上等价。

JavaScript 引擎优化
现代 JavaScript 引擎(V8、SpiderMonkey)拥有复杂的优化管道,这使基准测试变得复杂:
JIT 编译
JavaScript 是即时编译的。函数的前几次运行较慢(解释执行),然后引擎会分析“热”函数并将其编译为本地机器码。基准测试库通过预热函数来处理这个问题。
死代码消除
如果引擎检测到函数的结果从未被使用,它可能会完全优化掉该工作,从而给出误导性的快速结果。始终使用基准测试代码的结果。
内联缓存
引擎会缓存类型信息以加速重复操作。如果生产代码使用混合类型,而基准测试使用一致的类型,则可能不切实际地快。
流行的 JavaScript 基准测试库
Benchmark.js
经典选择,被 jsPerf.com 使用:
var suite = new Benchmark.Suite;
suite
.add('RegExp#test', function() {
/o/.test('Hello World!');
})
.add('String#indexOf', function() {
'Hello World!'.indexOf('o') > -1;
})
.run({ async: true });

tinybench
轻量级现代替代方案,支持异步和 TypeScript 类型。
Vitest bench
内置于 Vitest,适用于已使用 Vitest 测试框架的开发者。
宏观与微观基准测试
微基准测试
隔离测试单个函数或操作。运行快速,易于理解,但由于 JIT 和缓存预热效应,可能无法反映生产环境条件。
宏观基准测试
在真实条件下测试完整的工作流或功能。运行较慢,但更能代表实际性能。
对于大多数开发决策,针对正在优化的特定操作进行微基准测试就足够了。
使用基准测试构建器工具
我们的工具提供:
- 多个测试用例——同时添加和比较多个实现
- 设置/清理代码——初始化共享状态而不影响测量
- 迭代控制——配置每个测试运行的次数
- 实时结果——查看每秒操作数和相对性能
- 统计数据——查看均值、中位数和误差范围
- 复制结果——以格式化文本分享基准测试结果
编写你的竞争实现,点击运行,即可获得即时、统计有效的性能比较。