簡體   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