JavaScript 性能——除法还是乘法? /对*

Posted

技术标签:

【中文标题】JavaScript 性能——除法还是乘法? /对*【英文标题】:JavaScript Performance - Divide or Multiply? / vs * 【发布时间】:2012-05-10 13:59:28 【问题描述】:

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

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

我总是被教导除法比乘法慢,但我没有真正的证据……在我开始基准测试和运行测试之前,有人对此有意见吗?

【问题讨论】:

【参考方案1】:

虽然这两种操作都非常快,但乘法的性能略好于除法。在我的测试中(如下),我注意到 Chrome 和 IE 9 有 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);

【讨论】:

非常感谢您回答问题,而不是告诉大家我们已经知道的事情。这应该是选择的答案,imo。 我的浏览器是在有限硬件(ARM 单核)上运行的 Webkit Qt4 浏览器。您说得对,最大的问题是减少 DOM 操作,并且每个周期都很重要。您的测试有助于表明我们的系统需要优化而不是可读性。幸运的是,我们可以将 cmets 放入代码中以帮助理解,因为它们在压缩时会被删除。 这不是首选答案,我不知道。可靠的答案@GerardoLima 是的,@КонстантинВан,我刚刚在我的计算机上运行了这段代码,乘法比除法快 6%——我在 MacBook Pro 上的 NodeJs 16 上运行测试;我必须乘以计数器cnt *= 100,才能察觉到差异 再一次,我不建议让代码不那么明显来支持这样小的改进。如果您的问题是性能问题,那么在进入这个雷区之前,应该寻找其他更明显的地方——DOM 操作、网络调用、代价高昂的 同步代码块、...【参考方案2】:

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

这是由于 CPU 执行这些操作的方式:

请参阅 https://***.com/a/1148060/520857 以了解 x86(剧透:fmulfdiv 快 2-3 倍)

请参阅 https://***.com/a/17883319/520857 以了解 AMD(剧透:fmulfdiv 快 7 倍)

这些操作的速度太快了,对 IRL 影响不大,但如果你做了很多,你发现编译器没有转换为乘法(我不认为 javascript 引擎这样做,不要'不过不要引用我的话,快速的谷歌检查没有给我任何关于这个主题的信息),那么可能进行这种优化是有意义的如果你遇到因划分太慢而导致的性能瓶颈,这不太可能,因为在几乎所有应用程序中,您更可能受 I/O 限制而不是 CPU 限制。

编辑:如果您正在执行大量浮点计算,您可以考虑找到一种方法来使用您的 GPU 来执行这些操作,因为 GPU 在 FP 操作上的速度明显快于 CPU,您可以从快速的谷歌搜索开始再次:http://gpu.rocks/

【讨论】:

【参考方案3】:

我个人认为这在性能方面没有太大区别。如果您正在考虑这一点,那么您正在深入到微观层面。

代码的可读性比这样的微优化更重要。代码的可读性和易于理解,如果您绝对必须进行微优化,请稍后在您发现真正的瓶颈时再做。

【讨论】:

以上是关于JavaScript 性能——除法还是乘法? /对*的主要内容,如果未能解决你的问题,请参考以下文章

JS 除法运算

一个基础而奇怪的问题:算法执行加法乘法除法性能无区别?

整数乘法和除法之间意外的明显性能差异

javascript(js)的小数点乘法除法问题

Excel怎么进行乘法和除法

如何比较 C++ 中 log() 和 fp 除法的性能?