我遇到了字符串距离函数运行太慢的问题。我已经将其范围缩小到以下范围(时间用于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/
发布于 2015-11-13 01:38:41
你有3个测试用例:
带有代码3的
Math.min参数和类型转换(布尔到带有代码2参数的castMath.min调用,其中第二个调用具有2参数的类型int)Math.min调用,每个调用都没有类型转换代码<>G220>1和2&3还有另一个不同之处,那就是在一些参数上有额外的+ 1。我想这是个bug。
隐式类型转换似乎是最昂贵的。如果从1中删除隐式类型转换,则会得到:
dp[c + 257] = Math.min(dp[c + 1], dp[c + 256], dp[c] + (a[i] != b[j] ? 1 : 0));这需要250ms (vs 60ms为3)。这仍然表明,具有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的时间,这揭示了一些关于实现的信息。
浏览器供应商对常用功能进行了优化。如果带有2个以上参数的Math.min很少见,那么这些结果并不奇怪。您在这里看到的是Math.min有两个实现:一个是针对两个参数的实现,这是非常优化的;另一个是针对更多参数的实现,没有经过优化。对于v8,这是由apsiller确认的:v8 source on github
https://stackoverflow.com/questions/33677463
复制相似问题