2016-09-15 4 views
4

Я тестировал различные методы конкатенации массива не потому, что это действительно имеет значение для моего кода, а просто как в стороне, чтобы увидеть, где мы сейчас. Как и ожидалось, очень новый оператор распространения ES 2015 быстро избивается старым методом concat() на массивах Javascript.Почему [] .concat() быстрее, чем Array.prototype.concat()?

Однако, что удивило меня немного было, когда я сравнил эти два:

var a = b = c = [1,2,3,4,5]; 
 

 
// SLOWER (V8 and Edge, very slightly faster in Firefox) 
 
console.time('t1'); 
 
for (i = 0; i < 1000000; i++) { 
 
    Array.prototype.concat(a, b, c); 
 
}; 
 
console.timeEnd('t1') 
 

 
// FASTER (V8 and Edge, very slightly slower in Firefox) 
 
console.time('t2'); 
 
for (i = 0; i < 1000000; i++) { 
 
    [].concat(a, b, c); 
 
}; 
 
console.timeEnd('t2')

я тестировал, и побежал несколько раз, прежде чем делать следующий, на последних node.js , Chrome и Edge. С V8 (node.js, Chrome) результат еще больше, но даже для Edge первый вариант всегда четко - на V8 значительно - медленнее второго. В Firefox результаты обратные, но почти равные, поэтому давайте ограничим этот вопрос двумя другими браузерами (V8 и Chakra).

Так я спрашиваю просто из любопытства, так как я не предвидел это вообще,

1) Помимо производительности, есть ли практическая разница между этими двумя способами сцепить эти массивы?

2) Почему именно AFAICS создает один объект (массив) меньше другого (начальный массив) slower?

Редактировать: Я знаю, что методы одинаковы, поэтому я протестировал прямой доступ к методу прототипа вместо создания (неиспользуемого) объекта массива для доступа к нему. Я также знаю, что это зависит от браузера, а именно: почему я тестировал две системы на основе V8 (Chrome и node.js) и браузер Microsoft Edge, и б) почему я включил приведенный выше тестовый пример.

Кстати, этот вопрос получил 4 downvotes и «близко: слишком широкий» голос через считанные секунды после размещения его (!). Я хотел бы сделать довольно отчаянную просьбу, чтобы вы нашли время, чтобы на самом деле прочитать вопросы и подумать о них более 2 секунд, прежде чем переходить на кнопку голосования. Ни одна из первоначальных критики не оказалась правильной. Я включил в качестве примера исполняемый пример.

+3

'Array.prototype.concat' и' [] .concat' - это то же самое, поэтому, скорее всего, ваше тестирование ошибочно. – adeneo

+0

Вы можете запустить мой тест, поэтому я включил его. Что было бы ошибкой? Пожалуйста, скажите мне! –

+1

Вы попробовали их заменять и запускать последнее первое и т. Д. – adeneo

ответ

7

Array.prototype.concat необходимо разрешить в каждом цикле. Если вы будете искать эту функцию только один раз, вы увидите разные результаты. Это может варьироваться в зависимости от реализации среды выполнения.

var a = b = c = [1,2,3,4,5]; 
 

 
// Array.prototype.concat 
 
console.time('t1'); 
 
var apc = Array.prototype.concat; 
 
for (i = 0; i < 1000000; i++) { 
 
    apc.call([], a, b, c); 
 
}; 
 
console.timeEnd('t1') 
 

 
// [].concat 
 
console.time('t2'); 
 
for (i = 0; i < 1000000; i++) { 
 
    [].concat(a, b, c); 
 
}; 
 
console.timeEnd('t2') 
 

 
// They're the same: 
 
console.log(Array.prototype.concat === [].concat);

Чтобы получить более точные результаты, используйте надлежащую библиотеку бенчмаркинга (ликвидирует время прогрева, например).

+0

Вот и ответ! Невозможно отметить это в течение еще 10 минут. Я действительно не понимаю, почему я получил downvoted до -4 в SECONDS, когда только этот пост всех этих комментариев действительно получил правильный ответ. –

+0

Очень хороший ответ и объяснение! – Li357

+0

Вы находитесь на чем-то, но зачем это нужно решать на каждой итерации, когда для достижения этой функции используются все свойства и т. Д., И почему бы не использовать более короткий '[]', я имею в виду, Array.prototype.concat === [] .concat' правда? – adeneo

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