奇怪的JS性能问题
Strange JS performance issues
我的字符串距离函数工作速度太慢。我已经将其缩小到以下内容(时间用于10K字符串比较):
// desired behavior - 400ms
dp[c + 257] = Math.min(dp[c + 256] + 1, dp[c + 1] + 1, dp[c] + (a[i] != b[j]));
// this is somewhat faster - 300ms
dp[c + 257] = Math.min(dp[c + 256] + 1, dp[c + 1] + 1);
dp[c + 257] = Math.min(dp[c + 257], dp[c] + (a[i] != b[j]));
// even faster - 50ms
dp[c + 257] = Math.min(dp[c + 256] + 1, dp[c + 1] + 1);
dp[c + 257] = Math.min(dp[c + 257], dp[c] + (a[i] != b[j] ? 1 : 0));
因此,首先,将Math.min
拆分为两个调用比使用一次3个参数更快——这怎么可能呢?第二,为什么添加显式的第三表达式比依赖于从bool到int的隐式转换要快得多?
这是一把小提琴:https://jsfiddle.net/6bnLvbt6/
您有3个测试用例:
- 带有类型强制转换(bool到int)的3参数的
Math.min
-
2
Math.min
调用,每个调用带有2个参数,其中第二个调用具有类型强制转换 -
2
Math.min
调用,每个调用带有2个参数,但不带类型强制转换
在1和2&3,其中在一些自变量上存在额外的CCD_ 5。我认为这是一个bug。
隐式类型转换似乎是最昂贵的。如果从1
中删除隐式类型转换,则会得到:
dp[c + 257] = Math.min(dp[c + 1], dp[c + 256], dp[c] + (a[i] != b[j] ? 1 : 0));
这需要250ms
(相对于3的60ms
)。这仍然表明具有3个参数的Math.min
较慢。让我们调查更多。
如果您将测试用例简化为:
// 1
for(var i = 0; i < 10000; i += 1) {
Math.min(1, 2, 3);
}
// 2
for(var i = 0; i < 10000; i += 1) {
Math.min(1, 2);
Math.min(1, 3);
}
在我的机器上的结果是:1
取2500ms
,2
取87ms
。如果您在Math.min
中添加更多的参数,您会发现每增加一个参数,它就会在时间上整齐地增加500ms
,这就揭示了实现的一些内容。
浏览器供应商优化经常使用的功能。如果具有两个以上自变量的Math.min
是不常见的,则这些结果并不奇怪。您在这里看到的是,Math.min
有两个实现:一个用于两个参数,它确实得到了很好的优化,另一个用于更多参数,它没有得到优化。对于v8,这一点得到了apsillers:github 上的v8源
相关文章:
- 使用正则表达式评估电子邮件地址时出现性能问题
- 在循环中附加事件处理程序时出现浏览器性能问题
- 角度指令性能问题
- 奇怪的Kineticjs性能问题
- 使用HTML和JS的iPhone游戏中的性能问题,以及appMobi
- 菜单性能问题
- 性能问题:通用选择器与单独绑定
- 离子框架移动应用程序性能问题
- 性能问题高图表图和 socket.io
- 样式 DOM 上的 $.before() 性能问题
- Ajax发布到PHP脚本,每5秒查询一次MySQL数据库的性能/问题
- 循环的 JavaScript 性能问题
- 性能问题:存储对DOM元素的引用与使用选择器相比
- 很多主干视图-性能问题
- jquery性能问题,操作注册
- 在web工作者、快速定时器和$scope中遇到AngularJS性能问题$apply()
- 使用pixi和p5声音库制作的听觉反应视觉效果的性能问题
- 更多的 DOM 元素会产生性能问题
- 主要面临性能问题
- HTML 大图像性能问题