2012-06-06 4 views
0

Скажите, пожалуйста, каков более быстрый способ ввода значения в массив?Использование метода Array.push

Я написал простой тест, чтобы сравнить push и a[a.length]= методы:

push.js:

self.onmessage = function (event) { 
    var n = Number(event.data), 
     i, 
     pushAr = [], 
     pushStart, 
     pushDuration, 
     ar = [], 
     start, 
     duration, 
     message; 

    // Push 
    pushStart = new Date(); 
    for (i = 0; i < n; i += 1) { 
    pushAr.push(i); 
    } 
    pushDuration = new Date() - pushStart; 

    // explicit 
    start = new Date(); 
    for (i = 0; i < n; i += 1) { 
    ar[ar.length] = i; 
    } 
    duration = new Date() - start; 

    message = "N = " + n; 
    message += "\nPush duration: " + pushDuration + "; "; 
    message += "Length duration: " + duration; 

    self.postMessage(message); 
}; 

main.js:

var worker = new Worker("push.js"), 
    i; 

worker.onmessage = function (event) { 
    console.log(event.data); 
}; 

for (i = 4; i < 8; i += 1) { 
    worker.postMessage(Math.pow(10, i)); 
} 

И я получил следующие результаты :

Chrome:

N = 10000 
Push duration: 0; Length duration: 0 
N = 100000 
Push duration: 3; Length duration: 5 
N = 1000000 
Push duration: 56; Length duration: 90 
N = 10000000 
Push duration: 807; Length duration: 948 

Safari:

N = 10000 
Push duration: 1; Length duration: 4 
N = 100000 
Push duration: 2; Length duration: 2 
N = 1000000 
Push duration: 27; Length duration: 41 
N = 10000000 
Push duration: 283; Length duration: 461 

FireFox:

N = 10000 
Push duration: 1; Length duration: 0 
N = 100000 
Push duration: 2; Length duration: 2 
N = 1000000 
Push duration: 11; Length duration: 20 
N = 10000000 
Push duration: 279; Length duration: 412 

Похоже Array.push быстрее, но почему некоторые ЛИЭС использовать array length вместо этого? И какие бонусы такого метода? Почему Chrome работает так медленно? Может быть, существуют более быстрые методы?

+0

Различия в производительности слишком зависимы от реализации и недостаточно велики для получения значительных выигрышей. Не оптимизировать (преждевременно) (http://c2.com/cgi/wiki?PrematureOptimization); напишите самый чистый код, затем профиль, затем оптимизируйте. – outis

+1

Самый быстрый способ - отслеживать индекс, (array [i] = value) вместо того, чтобы измерять его на каждой итерации. – kennebec

ответ

2

Оба метода точно такие же, push быстрее, потому что один и тот же алгоритм (получение длины массива) работает внутри механизма сценария, а не в скрипте. ar [ar.length] может быть использован, если вам нужно, чтобы результат этого выражения был новым значением, например, в цепочке. somevar = ar[ar.length] = "some new value"

Я нашел еще одно возможное применение - совместимость со старыми версиями javascript-движка. В документации Microsoft для JScript версии 5.0 нет упоминания о методе push в объекте Array. И я фактически нашел свой собственный код с того времени (около 2000), который фактически использует код images[images.length] = s. Таким образом, возможно, массивы не всегда имеют метод push.

P.S. Да, MSDN cocumentation для нажимной методы говорит версии 5.5 требуется, и это было даже не в Windows 2000.

+0

Согласитесь, но возвращаемое значение не имеет значения. Если мы перейдем к реализации «push», мы увидим, что этот алгоритм делает гораздо больше, чем толкает значение в массив, есть также некоторые проверки типов аргументов и т. Д. Как это происходит быстрее? Родные оптимизации? – ValeriiVasin

+1

Да, массивы очень оптимизированы производителями; они являются хорошими аргументами в «быстрых машинных» дискуссиях. Какая версия, которую вы используете, скорее вопрос веры :-) http: // jsperf.com/index-vs-push/2 – Bergi

+0

Отличный тест и сайт. – ValeriiVasin

1

некоторых библиотек (например, JQuery) использовать ar[ar.length], потому что они не используют реальных массивов, но ArrayObjects, которые не имеют метода .push, потому что они являются объектами, а не массивами. Еще один трюк, который используется для решения этой проблемы, и что вы можете столкнуться часто является

Array.prototype.push.call(arrObj,'newValue'); 

Другая причина для использования ar[ar.length] упоминается Panda-34: прикованных назначения ..!

+1

Но тогда им придется использовать 'ar [ar.length ++]', не так ли? – Bergi

+0

Да, где-то они должны увеличивать длину объекта ArrayObject, хотя и не обязательно в самом задании. –

+0

Хорошая точка, спасибо. – ValeriiVasin

Смежные вопросы