Як прискорити оператор spread у JavaScript

4 хв. читання

Перш ніж ми дізнаємось, як саме покращити продуктивність spread-оператора у JavaScript, заглянемо під капот роботи з ітерованими об'єктами самого оператора.

Оператор spread, або три крапки, працює з масивами чи загалом з ітерованими об'єктами та розділяє їх на елементи, з яких формується новий масив.

Spread-оператор може стояти на будь-якій позиції всередині літералу масиву:

const numbers = [1, 2, 3];
[0, ...numbers];    // => [0, 1, 2, 3]
[0, ...numbers, 4]; // => [0, 1, 2, 3, 4]
[...numbers, 4];    // => [1, 2, 3, 4]

А тепер цікаве запитання: чи залежить продуктивність коду від розташування spread-оператора в масиві? Дізнаємось!

1. Створюємо допоміжні функції

Перед тим як почнемо порівняння продуктивності, оголосимо дві функції. Перша з них — appendToTail():

function appendToTail(item, array) {
  return [...array, item];
}

const numbers = [1, 2, 3];
appendToTail(10, numbers); // => [1, 2, 3, 10]

Суть створеної функції в тому, що вона вставляє числа в кінець масиву. Для цього ми використовуємо конструкцію [...array, item].

Наступна функція appendToHead():

function appendToHead(item, array) {
  return [item, ...array];
}

const numbers = [1, 2, 3];
appendToHead(10, numbers); // => [10, 1, 2, 3]

appendToHead() — чиста функція, яка повертає новий масив, де елементи додаються в початок масиву. Для цього використовуємо конструкцію [item, ...array].

Вам може здатися, що не має жодної різниці в продуктивності цих функцій. Але...

2. Тест продуктивності

Протестуємо швидкість конструкцій [...array, item] vs [item, ...array] на MacBook Pro в таких браузерах:

  • Chrome 76
  • Firefox 68
  • Safari 12.1

Результати перевірки:

Як прискорити оператор spread у JavaScript

Бачимо, що в браузерах Firefox та Safari обидва варіанти мають приблизно однакову продуктивність.

А от в Chrome конструкція [...array, item] відпрацьовує вдвічі швидше, ніж [item, ...array].

Тож щоб пришвидшити продуктивність spread-оператора у Chrome, використовуйте його на початку літералу масиву:

const result = [...array, item];

Виникає запитання: чому так відбувається?

3. Fast-path оптимізація

Починаючи з версії 7.2, рушій V8, який відповідає за виконання JavaScript у Chrome, підтримує оптимізацію spread-оператора: fast-path оптимізацію.

Коротко пояснимо принцип її роботи.

Без оптимізації, коли рушій натрапляє на оператор spread, викликається метод ітератора iterator.next() для ітерованого об'єкта. На кожній ітерації пам'ять кінцевого масиву збільшується і додається новий елемент.

Однак з fast-path оптимізацією ми уникаємо створення об'єкта ітератора взагалі. Рушій визначає довжину розширеного масиву і виділяє пам'ять лише раз для кінцевого масиву. Далі кожен елемент розширеного масиву додається в кінцевий. У такий спосіб і збільшується продуктивність.

4. Підтримувані структури даних

Fast-path оптимізація застосовується до таких структур даних у JavaScript:

Масиви

const numbers = [1, 2, 3, 4];

[...numbers, 5]; // => [1, 2, 3, 4, 5]

Рядки

const message = 'Hi';

[...message, '!']; // => ['H', 'i', '!']

Сети

const colors = new Set(['blue', 'white']);

[...colors, 'green'];          // => ['blue', 'white', 'green']
[...colors.values(), 'green']; // => ['blue', 'white', 'green']
[...colors.keys(), 'green'];   // => ['blue', 'white', 'green']

Map

Підтримується лише для методів map.keys() та map.values():

const names = new Map([[5, 'five'], [7, 'seven']]);

[...names.values(), 'ten']; // => ['five', 'seven', 'ten']
[...names.keys(), 10];      // => [5, 7, 10]

Висновок

Коли ми використовуємо оператор spread на початку масиву, продуктивність коду збільшується завдяки fast-path оптимізації. Вона доступна в рушії V8 з версії 7.2 (представлено у Chrome v72 та NodeJS v12).

Тести продуктивності показують, що можна досягнути подвійного пришвидшення, якщо використовувати конструкцію [...array, item], а не [item, ...array].

Звісно, fast-path — корисна річ, однак варто звертати на це увагу лише при роботі з великими масивами, коли продуктивність дійсно дуже важлива.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація