繁体   English   中英

Javascript-将数组部分复制到另一个中的最快方法

[英]Javascript - Fastest way of copying an array portion into another

我需要将FAST的一部分数组复制到另一个数组中,以替换它的旧值。

  • 无需范围检查。
  • 复制项目数:16384
  • 数组仅包含整数

基准代码: http//codebase.es/test/copytest.htm

这是我的方法:

  var i = 0x4000>>5; // loops count
  var j = 0x4000;    // write start index
  var k = 0x8000;    // read start index
  while (i--) {      // loop unrolling
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];    
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];
    //8
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];    
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];
    //16
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];    
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];
    //24
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];    
    dst[j++]=src[k++]; dst[j++]=src[k++];
    dst[j++]=src[k++]; dst[j++]=src[k++];
    //32
  }    

可以更快地完成吗?

我不确定您的方法是否比这更快:

var i = 0x4000;     // loops count
var j = 0x4000;    // write start index
var k = 0x8000;    // read start index
while (i--) {      // loop unrolling
  dst[j++]=src[k++];
}

您可以继续展开循环以提高性能,但看起来这和您要获得的速度差不多。 正如Gumbo在评论中所述,请尝试使用前增量而不是后增量:

var i = 0x4000>>5 + 1; // loops count
var j = 0x4000 - 1;    // write start index
var k = 0x8000 - 1;    // read start index
while (--i) {      // loop unrolling
    dst[++j]=src[++k]; dst[++j]=src[++k];
    dst[++j]=src[++k]; dst[++j]=src[++k];    
    dst[++j]=src[++k]; dst[++j]=src[++k];
    dst[++j]=src[++k]; dst[++j]=src[++k];
    //8
    ...

我会考虑切片方法:

var dst = src.slice(start,end)

性能取决于javascript引擎的实现,但是大概所有的浏览器都在其平台上实现了尽可能高的效率。

在这里查看更多

抱歉,一年后,但是..这在FF中最快:

function copy4() {
  var i = 0x4000; // loops count
  var j = 0x4000; // write start index
  var k = 0x8000; // read start index

  var args = src.slice(k, k+i);
  args.unshift(i);
  args.unshift(j);
  Array.prototype.splice.apply(dst,args);
}

另一种值得进行基准测试的方法可能是仅使用一些强大的基元来构建全新的dst阵列,而不是执行循环,即:

dst = dst.slice(0, writestart).concat(
    src.slice(readstart, readstart+count),
    dst.slice(writestart+count));

毫无疑问,这种方法的性能与循环的性能将随所涉及的数组长度和计数以及底层的Javascript引擎而有所不同-猜测不会非常有效,这就是为什么我建议进行基准测试的原因;-)。

尝试结合使用内置方法slicesplice

Array.prototype.splice.apply(dst, [j, i].concat(src.slice(k, k+i)));

您可以创建一个完全展开的版本,例如通过

function compileCopy(count, di, si) {
    var sb = new Array(count);
    di += count, si += count;
    while(count--) sb[count] = --di + ']=src[' + --si;
    return new Function('dst[' + sb.join('];dst[') + '];');
}

var copy = compileCopy(0x4000, 0x4000, 0x8000);

在Opera中,它将比循环版本稍快。 在FF中...不行(某处甚至可能有错误)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM