我有一个jsperf测试用例 http://jsperf.com/multiplication-vs-division-lars,结果非常令人困惑。我有三个“片段”:
大多数时候,它们的速度都相同......甚至是控制!我猜测 JS JIT 编译器是删除我的“不必要的”指示 https://blog.mozilla.org/javascript/2014/07/15/ionmonkey-optimizing-away/当它们似乎没有任何效果时;所以我开始累积结果并将其记录到控制台 https://stackoverflow.com/a/4871762/423105当测试循环完成时,例如
for (var i = 0; i < nNumbers; i++) {
result += a[i] / b[i];
}
console.log(result);
但是,当控制台打开时和不打开时,我得到了截然不同的结果。控制台日志记录的减慢似乎压倒了任何其他性能问题。
因此,我尝试增加每个“片段”中的迭代次数,以最大程度地减少与我尝试测试的操作相关的日志记录量。但我仍然发现这三个片段之间没有显着的速度差异。真的,除法和乘法与计算常数的速度大致相同?我一定做错了什么。或者 jsperf 坏了。
已经回答了一些相关问题,但我没有发现专门针对 Javascript 基准测试的问题。
- 如何防止 Rust 基准库优化我的代码? https://stackoverflow.com/questions/32385805/how-can-i-prevent-the-rust-benchmark-library-from-optimizing-away-my-code
- 我如何确定编译器不会优化我的性能测试? https://stackoverflow.com/questions/4871550/how-can-i-be-sure-that-the-compiler-doesnt-optimize-away-my-performance-test
不要放console.log
s 在你的定时部分。与您实际想要测量的操作相比,它的速度非常慢,因此它会扭曲您的结果。另外 - 正如您所注意到的 - 当控制台打开或不打开时,它的时间会有所不同。
您可以通过将结果放入全局数组来防止去优化。优化器只能删除代码 https://en.wikipedia.org/wiki/Dead_code_elimination这不会影响结果,如果它操纵全局状态,这是不可能的。
当然,这仍然不一定能阻止循环不变代码运动 https://en.wikipedia.org/wiki/Loop-invariant_code_motion,因此您还需要确保您的定时代码始终对不同的数据进行操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)