JavaScript性能 - 除法还是乘法? / vs *

时间:2012-05-10 13:59:29

标签: javascript performance

我正在编写一个非常重的JavaScript应用程序(它几乎都是JavaScript),并且它确实需要大量的数据来迭代(JSON),并且必须执行算术某些任务。性能是该应用程序的主要考虑因素。我已经介绍了Webworkers以帮助解决这个问题,我试图不再依赖于像jQuery这样的lib提供的方法(比如.each()而不是for循环)。无论如何,这是一个简单的问题......

在申请中,我必须应用价格变动,这将涉及许多涉及分割的数字过程。记住,这将发生成千上万次对我来说总是通过乘法或乘法和除法的混合来应用变化会更好。例如,我可以通过乘以0.5或除以2来应用50%的折扣。

我总是被告知分裂比乘法慢,但我没有真正的证据......在开始基准测试和运行测试之前,有没有人对此有意见?

3 个答案:

答案 0 :(得分:51)

尽管两种操作都非常快,但乘法的性能略好于除法。在我的测试中(下面),我注意到Chrome上有14%的差异,IE 9有10%的差异。如果你必须从浏览器中挤出这个性能,你可以在进入之前将分频器转换为乘数循环,但我认为将可读性降低到如此微小的改进并不是一个好主意。

var cnt = 500000;
var rls = []
var ags = [[2,1], [4,2], [7,3], [4e0,1], [32e0,2], [37e0,3], [-37e7,(7e3/3e-4)]];
var fns = [
  {name: "fn_mul", fn: (function(x, y) { return x * y; })},
  {name: "fn_div", fn: (function(x, y) { return x / y; })}
]

// setup  ---------------------------------------
for(var iag=0; iag<ags.length; iag++) {
  if(Object.prototype.toString.call(ags[iag]) !== "[object Array]") {
    ags[iag] = [ags[iag]]
  };
}

// run ------------------------------------------
for(var ifn=0; ifn<fns.length; ifn++) {
  var fn = fns[ifn].fn;
  var ts = (new Date()).valueOf();
  for(var iag=0; iag<ags.length; iag++) {
    var ag = ags[iag];
    for(var icn=0; icn<cnt; icn++) { fn.apply(this, ag); }
  }
  rls.push({"name": fns[ifn].name, "ts": (new Date()).valueOf() - ts});
}
dump(rls);

答案 1 :(得分:1)

我个人认为在性能方面没有太大区别。如果你正在考虑这个问题,那么你就可以达到微观水平了。

您的代码的可读性比这样的微优化更重要。可读性和易于理解的代码,如果您必须进行微优化,请在以后找到真正的瓶颈时执行此操作。

答案 2 :(得分:1)

要为此增加更多的上下文,前提是编译器不优化对乘法的除法(例如n / 2转换为n * 0.5),则乘法总是比除法更快。 / p>

这是由于CPU如何执行这些操作所致:

有关x86的信息,请参见https://stackoverflow.com/a/1148060/520857(扰流器:fmulfdiv快2-3倍)

有关AMD的信息,请参见https://stackoverflow.com/a/17883319/520857(扰流器:fmulfdiv快7倍)

这些操作的速度太快,无法满足许多IRL的要求,但是如果您执行了很多操作,却发现编译器没有转换为乘法(我不认为javascript引擎会这样做,虽然没有引用我,但快速的Google检查并没有提供有关该主题的任何信息),所以可能使这种优化如果由于划分速度太慢而导致性能瓶颈,这种情况不太可能发生,因为在几乎所有应用程序中,与CPU绑定相比,与I / O绑定的可能性更大。

编辑:如果您要进行大量的浮点计算,则可以考虑找到一种使用GPU来执行这些操作的方法,因为FP ops上的GPU比CPU上的GPU显着更快,从而让您从谷歌快速搜索中入手再次:http://gpu.rocks/