簡體   English   中英

用JavaScript將數組長度加倍的最快方法?

[英]Fastest way to double the length of an array in JavaScript?

[1,2,3,4,5].duplicate(); // [1,2,3,4,5,1,2,3,4,5]

也許像這樣:

var array = [1,2,3,4,5];
array.push(array);

但是最快的方法是什么?

您可以使用concat並將原始數組替換為新數組:

array = array.concat(array);

或使用apply push (修改原始數組):

[].push.apply(array, array);

或使用傳播運算符 push (修改原始數組):

array.push(...array);

在JS中做某事的最快方法通常是使用類似C的簡單本機語句。

我認為這將是最快的:

function duplicate(arr) {
      for(var i=0,len=arr.length;i<len;i++)
            arr[i+len]=arr[i];
}

一個較慢但更優雅的方法是:

arr=arr.concat(arr);

或者這個:

[].push.apply(arr,arr);

EcmaScript 6還允許您使用傳播運算符執行相同的操作 該運算符只是將數組的所有值都放在您編寫的位置,因此,此var arr = [0,1,2,3];console.log(...arr)變成var arr = [0,1,2,3];console.log(0,1,2,3)

arr.push(...arr);

但是,EcmaScript 6 尚未得到廣泛支持 (並且該功能也沒有),因此,如果您是我,我將不使用它。 盡管ES 6剛剛被批准並發布(如@LyeFish在評論中所述),但大多數瀏覽器仍在使用它。

EcmaScript-262第6版在5天前正式發布(感謝@LyeFish)! http://www.ecma-international.org/news/index.html

根據我的測試結果來看,獲獎者是concat其次是push方法。 我還測試了循環方法和我自己新引入的splice例程。

這是使用的測試“基礎結構”代碼:

var toArray = Function.prototype.call.bind(Array.prototype.slice);

Function.prototype.testerTimes = function(number) {
    var func = this;
    return function() {
        var args = toArray(arguments), i = 0;
        for( ; i < number; func.apply(this, args), i++);
    };
};

Function.prototype.testerTime = function(units) {
    var func = this;
    return function() {
        var start = Date.now(), diff;
        func.apply(this, toArray(arguments));
        diff = Date.now() - start;
        return units === "s" ? diff / 1000 : units === "m" ? diff / 60000 : units === "h" ? diff / 3600000 : diff;
    };
};

Function.prototype.testerToConsole = function(prefix, message) {
    var func = this;
    return function() {
        console.log(prefix + message + func.apply(this, toArray(arguments)));    
    };
};

Function.prototype.makeTestReady = function(times, units, prefix, message) {
    return this.testerTimes(times).testerTime(units).testerToConsole(prefix, message);
};

這是測試代碼:

function genArray(num) {
    for(var i = 0, arr = []; i < num; arr.push(++i));
    return arr;
};

var numberOfRuns = 1000000;
var timeUnit = "s";
var messagePrefix = "   ";

var funcs = [
    function duplicateConcat(arr) {
        var arrCopy = arr.slice(0);
        return arrCopy.concat(arrCopy);    
    },

    function duplicatePush(arr) {
        var arrCopy = arr.slice(0);
        arrCopy.push.apply(arrCopy, arrCopy);
        return arrCopy;
    },

    function duplicateLoop(arr) {
        var arrCopy = arr.slice(0);
        for(var i = 0, len = arrCopy.length; i < len; i++) {
            arrCopy[len + i] = arrCopy[i]; 
        }    
        return arrCopy;
    },

    function duplicateSplice(arr) {
        var arrCopy = arr.slice(0);
        arrCopy.splice.apply(arrCopy, [arrCopy.length, 0].concat(arrCopy));
        return arrCopy;
    }
].map(function(func, index, arr) {
    return func.makeTestReady(numberOfRuns, timeUnit, messagePrefix, func.name + ": ");
});

for(var i = 5; i < 25; i+= 5) {
    console.log(i + "-element array:");
    funcs.forEach(function(func) {
        func(genArray(i));
    });
}

並且,這是大小為5、10、15和20的數組的每個函數運行1,000,000次的結果:

5-element array: 
   duplicateConcat: 0.236  
   duplicatePush: 0.228 
   duplicateLoop: 0.372 
   duplicateSplice: 0.45
10-element array: 
   duplicateConcat: 0.241  
   duplicatePush: 0.273    
   duplicateLoop: 0.433 
   duplicateSplice: 0.48  
15-element array:
   duplicateConcat: 0.261 
   duplicatePush: 0.293
   duplicateLoop: 0.5
   duplicateSplice: 0.522 
20-element array: 
   duplicateConcat: 0.24 
   duplicatePush: 0.311
   duplicateLoop: 0.602 
   duplicateSplice: 0.558

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM