0

背景故事

我正在寻找 2 的大幂。我的方法是将大数拆分为一个较小值的数组,然后将它们中的每一个相乘以获得下一个值。我为较小的块选择的最大大小为1e15. 然后我决定看看如果我使用新的数组缓冲区并且必须将最大大小减小到1e9. 发生了一些奇怪的事情,我得到的性能提升不是来自使用数组缓冲区,而是来自使用更小的整数。这是没有意义的,因为数字越大,函数循环遍历数组的次数就越少。

代码

var i=3
function run(){
  loop(50000,Math.pow(10,i),i++);
  if(i<16)setTimeout(run,100)
}
run();

function loop(pin,lim,id){
  var pow=110503;
  pow=pin||pow;
  var l=pow-1,val=[2];
  var t1,t2;
  //console.time(id);
  t1=new Date();
  while(l--){
    val=multiply(val,lim);
  }
  //console.timeEnd(id);
  t2=new Date();
  console.log(id,' ',t2-t1);
}

function multiply(a,lim){
  var l=a.length,val=0,carry=0;
  while(l--){
    val=a[l]*2+carry;
    carry=0;
    if(val>lim-1){
      var b=val%lim;
      carry=(val-b)/lim;
      val=b;
    }
    a[l]=val;
  }
  if(carry>0){a.unshift(carry)}
  return a;
} 

结果

IE10

 3 5539 
 4 4213 
 5 3329 
 6 2720 
 7 2341 
 8 2153 
 9 1948 
 10 1699 
 11 1508 
 12 1401 
 13 1309 
 14 1208 
 15 1133 

铬合金

3 5962
4 4385
5 3851
6 3242
7 2533
8 2207
9 1940
10 1794
11 1542
12 1604
13 1560
14 1414
15 1331

火狐

3 3651 
4 2732 
5 2279 
6 1853 
7 1615 
8 1408 
9 1256 
10 2375 
11 2034 
12 1874 
13 1723 
14 1600 
15 1504

问题

如您所见,Firefox 的性能优于 IE10 和 Chrome,直到 9 位数长的数字,然后它需要一个突然的时间跳跃。那么,它为什么要这样做呢?我想这可能与在可以存储在 32 个字节中的数字之间切换有关。我想使用 32 字节数字更有效;所以对于较小的数字,他们使用它们,然后在需要时切换到更大的整数类型。但如果这是真的,为什么它永远无法赶上 Chrome 和 IE 的性能,并且切换会导致这么多的性能损失?

4

1 回答 1

0

SpiderMonkey (Firefox) 和 V8 (Chrome) 都尽可能使用 32 位整数,当数字不再适合 32 位 int 时切换到双精度数(不是更大的整数)。但请注意,“can”是启发式确定的,因为混合双精度和整数是有成本的,因为必须来回转换,所以 V8 可能没有决定在这里专门处理整数。

编辑:删除了关于需要来源的部分,因为它在原帖中就可以了!

于 2013-03-18T13:16:15.067 回答