简体   繁体   English

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

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

I need to copy FAST a portion of an array into another, replacing it's old values. 我需要将FAST的一部分数组复制到另一个数组中,以替换它的旧值。

  • No range checkings needed. 无需范围检查。
  • Number of items to copy: 16384 复制项目数:16384
  • The array only contains integers 数组仅包含整数

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

This is my approach: 这是我的方法:

  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
  }    

can this be done faster? 可以更快地完成吗?

Im not sure your method is faster than this: 我不确定您的方法是否比这更快:

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++];
}

You could keep unrolling the loop for even slighter increases in performance, but it seems like this is just about as fast as you're going to get it. 您可以继续展开循环以提高性能,但看起来这和您要获得的速度差不多。 As Gumbo stated in a comment, try using pre-increment instead of post-increment: 正如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
    ...

I would consider the slice method: 我会考虑切片方法:

var dst = src.slice(start,end)

The performance depends on the implementation of javascript engine, but presumably all the browsers have implemented as efficient as possible on their platform. 性能取决于javascript引擎的实现,但是大概所有的浏览器都在其平台上实现了尽可能高的效率。

See more here 在这里查看更多

Sorry, one year later, but.. this is fastest in FF: 抱歉,一年后,但是..这在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);
}

An alternative worth benchmarking may be building a brand new dst array with just a few powerful primitives rather than performing the loop, ie: 另一种值得进行基准测试的方法可能是仅使用一些强大的基元来构建全新的dst阵列,而不是执行循环,即:

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

How the performance of this approach compares to looping will no doubt vary with the array lengths and counts involved, as well as with the underlying Javascript engine -- guessing would not be very productive, which is why I suggest benchmarking instead;-). 毫无疑问,这种方法的性能与循环的性能将随所涉及的数组长度和计数以及底层的Javascript引擎而有所不同-猜测不会非常有效,这就是为什么我建议进行基准测试的原因;-)。

尝试结合使用内置方法slicesplice

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

You can create a completely unrolled version, eg via 您可以创建一个完全展开的版本,例如通过

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);

In Opera, it will be slightly faster than the looping version. 在Opera中,它将比循环版本稍快。 In FF... not (there might even be some bug somewhere). 在FF中...不行(某处甚至可能有错误)。

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

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