我写了这个:
var max = 0xffffff * 4;
var step = 1 / max;
function cube() {
var result = 0.;
for (var x = 0.; x < 1; x += step) {
result += x * x * x;
}
return result;
}
function mul() {
var result = 0.;
for (var x = 0.; x < 1; x += step) {
result += x * x;
}
return result;
}
function go() {
var r = '';
r += cube() + ' \n';
r += mul() + ' \n';
alert(r);
}
并在Chrome Profiler中查看结果:
mul: 106ms
cube: 87ms
这怎么可能?
答案 0 :(得分:34)
你的断言是完全错误的。 cube不比mul快,你的例子不能证明它。
实际上,Javascript执行的内部需要比实际的乘法花费更多的时间,导致mul和cube的时间非常相似。我在一个循环中运行了两个函数,只是为了增加差异,而分析器显示20219 vs 20197,这是微不足道的。顺便说一句,立方体在这里是“慢”的。此外,这种分析方法不起作用,因为Chrome和Firefox在循环中进行数学运算之前都进行了很多优化。您认为循环可以很好地使用缓存值,甚至是优化所知的数学函数返回相同的结果。
以下是我使用的代码:
<script>
var max = 0xffffff * 4;
var step = 1 / max;
function cube() {
var result = 0.;
for (var x = 0.; x < 1; x += step) {
result += x * x * x;
}
return result;
}
function mul() {
var result = 0.;
for (var x = 0.; x < 1; x += step) {
result += x * x;
}
return result;
}
function go() {
var s='';
for (var i=0; i<100; i++) {
s+=cube();
s+=mul();
}
console.log(s);
}
go();
</script>
此外,仅作为参考,请观看视频:https://fosdem.org/2016/schedule/event/mozilla_benchmarking_javascript_tips/ Firefox家伙解释为什么microbenchmarking并不是真正意义重大。
答案 1 :(得分:0)
这可能是因为因为你的所有数字都低于1,所以立方体函数正在添加比正方形更小的数字(我不确定这是否实际上是如何工作的)因此花费的时间更少。这只是猜测。而且由于数字太小,这也可能是由于精度不足。此外,我测试了数字超过一个立方体与他们相比较慢。
答案 2 :(得分:0)
也许优化器决定其中一个可以使用向量指令执行,而另一个使用普通的旧fmul。我推测'square'使用fmul和cube使用向量指令mulpd,它可以在一条指令中乘以最多4个双精度数。我添加了一个“四边形”,它做了4次乘法,它的时间非常接近立方体。但当我去'五'时,它的速度慢于平方。这是一些间接证据,表明向量指令用于立方体和四边形。
在平板电脑上查看intel cpu vs arm的结果会很有趣。
答案 3 :(得分:-5)
在某些浏览器上,当JIT在后台编译时,javascript会在解释时开始。一旦javascript被编译,它就会开始运行得更快。