首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Math.imul()在输入很少的情况下比常规乘法(*)快,而在大量输入的情况下要慢呢?

为什么Math.imul()在输入很少的情况下比常规乘法(*)快,而在大量输入的情况下要慢呢?
EN

Stack Overflow用户
提问于 2017-02-21 04:26:30
回答 1查看 338关注 0票数 5

我一直在尝试Math.imul()方法,我发现它在输入很少的情况下速度更快,在输入很多的情况下速度更慢。为什么会这样呢?

(也许它与Math.imul()本身无关,但这并不重要,我仍然对理解我得到的结果感兴趣。)

代码:

代码语言:javascript
复制
const base_multiplier = 40;
const input_counts = [
    base_multiplier,
    base_multiplier * 10,
    base_multiplier * 100,
    base_multiplier * 1000
];
for (const input_count of input_counts) {

    const value_pairs = Array
        .from({ length: input_count })
        .map(() => [
            Math.round(Math.random() * 100),
            Math.round(Math.random() * 100)
        ])

    console.time(`${input_count} inputs | Standart multiplication`);
    eval('value_pairs.forEach(([x, y]) => x * y)')
    console.timeEnd(`${input_count} inputs | Standart multiplication`);

    console.time(`${input_count} inputs | Imul multiplication`);
    eval('value_pairs.forEach(([x, y]) => Math.imul(x, y))')
    console.timeEnd(`${input_count} inputs | Imul multiplication`);

}

Chrome控制台的输出:

代码语言:javascript
复制
40 inputs | Standart multiplication: 0.048ms
40 inputs | Imul multiplication: 0.043ms
400 inputs | Standart multiplication: 0.031ms
400 inputs | Imul multiplication: 0.063ms
4000 inputs | Standart multiplication: 0.826ms
4000 inputs | Imul multiplication: 3.604ms
40000 inputs | Standart multiplication: 0.834ms
40000 inputs | Imul multiplication: 0.898ms

Node的输出:

代码语言:javascript
复制
40 inputs | Standart multiplication: 0.510ms
40 inputs | Imul multiplication: 0.064ms
400 inputs | Standart multiplication: 0.569ms
400 inputs | Imul multiplication: 0.108ms
4000 inputs | Standart multiplication: 0.172ms
4000 inputs | Imul multiplication: 3.253ms
40000 inputs | Standart multiplication: 0.502ms
40000 inputs | Imul multiplication: 0.762ms
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-23 09:33:04

基本的答案是,Math.imul*的乘法是不同的,因此不应该像这样进行比较。Math.imul执行32位整数乘法,但仍然必须接受java脚本编号作为输入。因此,它必须执行额外的操作来转换和/或确保输入是整数。(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul )

这意味着Math.imul(a,b)接受Js浮点数并产生类似于Math.floor(a) * Math.floor(b)的结果

为了使测试更准确,我们可以尝试使用Uint32数组,对Math.random结果进行舍入,确保所有分配发生在循环开始处,并在结束时计算和,以防止编译器优化mul操作。

结果仍然不明确,我怀疑这归结于整数运算带来的imul速度增益与转换和函数调用的损失之间的平衡。而这种平衡是大小相关的。

代码语言:javascript
复制
var base = 40;
var input = [base, base * 10, base * 100, base * 1000];
for (var j = 0; j < input.length; ++j) {
  var length = input[j];
  var arrayX = new Uint32Array(length);
  var arrayY = new Uint32Array(length);
  var im = new Uint32Array(length);
  var sm = new Uint32Array(length);

  for (var i = 0; i < input[j]; ++i) {
    arrayX[i] = Math.round(Math.random() * 100);
    arrayY[i] = Math.round(Math.random() * 100)
  }

  console.time(input[j] + ' inputs | Standard multiplication');
  for (var i = 0; i < length; ++i) {
    sm[i] = arrayX[i] * arrayY[i];
  }
  console.timeEnd(input[j] + ' inputs | Standard multiplication');

  console.time(input[j] + ' inputs | Imul multiplication');
  for (var i = 0; i < length; ++i) {
    im[i] = Math.imul(arrayX[i], arrayY[i]);
  }
  console.timeEnd(input[j] + ' inputs | Imul multiplication');

  // Prevent multiplication from being optimized away
  var sum = 0;
  for (var i = 0; i < length; ++i) {
    sum += sm[i];
    sum += im[i];
  }
  console.log(sum);
}

在我的机器上的Chrome中,对于40000或更大的输入大小,imul现在比标准的*乘法略快一些。而4000大小的情况对于imul来说仍然很慢。但是,如果基数更改为35,则它们大致相等。如果基数更改为55,则*将比imul慢得多。

代码语言:javascript
复制
40 inputs | Standard multiplication: 0.120ms
40 inputs | Imul multiplication: 0.035ms
203634
400 inputs | Standard multiplication: 0.045ms
400 inputs | Imul multiplication: 0.050ms
1967184
4000 inputs | Standard multiplication: 0.290ms
4000 inputs | Imul multiplication: 2.935ms
20062298
40000 inputs | Standard multiplication: 0.605ms
40000 inputs | Imul multiplication: 0.450ms
199130538


55 inputs | Standard multiplication: 0.130ms
55 inputs | Imul multiplication: 0.040ms
237716
550 inputs | Standard multiplication: 0.070ms
550 inputs | Imul multiplication: 0.060ms
2638770
5500 inputs | Standard multiplication: 3.175ms
5500 inputs | Imul multiplication: 0.095ms
27218460
55000 inputs | Standard multiplication: 0.850ms
55000 inputs | Imul multiplication: 0.575ms
277160962
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42353622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档