Почему разрыв в производительности между массивами литералов и BufferArray такой большой? - PullRequest
0 голосов
/ 19 мая 2019

Я пытаюсь понять ArrayBuffer в js как один из переносимых типов между потоком и рабочим.

Я обнаружил огромный разрыв в производительности при создании переменной и не могу найти ответ на этот вопрос.Интернет.

Я пробовал несколько сравнительных тестов, и литералы массивов всегда намного быстрее объявлялись, чем TypedArrays.Я пытался в узле 11, Chrome и Firefox, результаты согласованы.

var LIMIT = 10000;
console.time("Array insertion time");
for (var i = 0; i < LIMIT; i++) {
    var arr = new Array();
}
console.timeEnd("Array insertion time");


console.time("ArrayBuffer insertion time");
for (var i = 0; i < LIMIT; i++) {
  var buffer = new ArrayBuffer(LIMIT * 4);
  var arr = new Int32Array(buffer);
}
console.timeEnd("ArrayBuffer insertion time");

Я получаю сумасшедшие результаты:
Время вставки массива: 1.283ms
Время вставки ArrayBuffer: 53.979ms

Я думал, что для JS Engine будет быстрее объявить TypedArray, чем литерал.Я думал, что ArrayBuffer был очень оптимизированным вызовом для выделения памяти для программы.

Ответы [ 2 ]

3 голосов
/ 23 мая 2019

Вы просто не делаете одно и то же ...

Когда вы объявляете ArrayBuffer, браузер запрашивает слот статической памяти, размер этого ArrayBuffer.
С другой стороны, массив не имеет статического слота памяти, он будет переназначен, а его длина будет обновлена.

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

var LIMIT = 5000; // I have to lower the LIMIT because Array is so slow
console.time("Array insertion time");
for (var i = 0; i < LIMIT; i++) {
  // to be fair, they should hold the same data
  var arr = new Array(LIMIT * 4).fill(0);
}
console.timeEnd("Array insertion time");


console.time("ArrayBuffer insertion time");
for (var i = 0; i < LIMIT; i++) {
  var buffer = new ArrayBuffer(LIMIT * 4);
  var arr = new Int32Array(buffer);
}
console.timeEnd("ArrayBuffer insertion time");
0 голосов
/ 19 мая 2019

Примитивные типы обычно всегда будут быстрее.Они используются так часто, что получают наибольшее внимание для оптимизации в двигателе.Типизированные массивы, скорее всего, имеют больше накладных расходов, потому что они выполняют проверки типов для таких операций, как вставка.Это не бесплатно.

Кроме того, ваш второй пример проделывает большую работу, объявляя буфер, а затем преобразовывая его в типизированный массив.Вы также выполняете очень маленькие операции, когда ArrayBuffers предназначены для хранения гораздо больших длинных буферов, таких как двоичное аудио или изображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...