7

Самый быстрый способ дублирования массива в JavaScript: slice против цикла 'for'

7

Вопрос: Какой из следующих способов дублирования массива в JavaScript быстрее?

  1. Метод slice:
var dup_array = original_array.slice();
  1. Цикл for:
for(var i = 0, len = original_array.length; i < len; ++i)
   dup_array[i] = original_array[i];

Я понимаю, что оба способа делают только поверхностную копию: если original_array содержит ссылки на объекты, то объекты не будут клонированы, а только ссылки будут скопированы, из-за чего оба массива будут ссылаться на одни и те же объекты. Но это не суть моего вопроса.

Я спрашиваю только о производительности. Какой метод будет быстрее?

5 ответ(ов)

3

С точки зрения производительности, slice действительно является самым быстрым способом. Тем не менее, он работает еще быстрее, если вы укажете индекс начала равным 0.

Пример:

myArray.slice(0);

работает быстрее, чем

myArray.slice();

Вы можете проверить это по ссылке: https://jsben.ch/F0SZ3.

1

В контексте ES6 (или ECMAScript 2015), более современный способ создать копию массива — это использовать оператор расширения (spread operator). Вот как это можно сделать:

arr2 = [...arr1];

Этот синтаксис создает новый массив arr2, который является копией массива arr1. Оператор ... развертывает элементы arr1 и добавляет их в новый массив arr2. Это удобно, так как такой способ легко читается и не требует использования методов вроде Array.prototype.slice(), что делает код более лаконичным и ясным.

0

Самый простой способ глубокого клонирования массива или объекта в JavaScript — это использовать метод JSON.parse вместе с JSON.stringify. Вот пример:

var dup_array = JSON.parse(JSON.stringify(original_array));

Этот подход работает, поскольку преобразует объект или массив в строку JSON, а затем распарсит его обратно в новый объект или массив, тем самым создавая глубокую копию. Однако имейте в виду, что этот метод не работает с элементами, которые не могут быть сериализованы в JSON, такими как функции, специальные объекты (например, Date, Map, Set и т.д.) или циклические ссылки. Если вам нужно учесть такие случаи, рассмотрите использование библиотек, таких как Lodash с методом _.cloneDeep().

0

🏁 Самый быстрый способ клонирования массива

Я создал эту простую утилитарную функцию, чтобы протестировать время, которое требуется для клонирования массива. Она не является на 100% надежной, но может дать общее представление о том, сколько времени требуется для клонирования существующего массива:

function clone(fn) {
  const arr = [...Array(1000000)];
  console.time('timer');
  fn(arr);
  console.timeEnd('timer');
}

Я протестировал разные подходы:

1)   5.79ms -> clone(arr => Object.values(arr));
2)   7.23ms -> clone(arr => [].concat(arr));
3)   9.13ms -> clone(arr => arr.slice());
4)  24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
5)  30.02ms -> clone(arr => [...arr]);
6)  39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
7)  99.80ms -> clone(arr => arr.map(i => i));
8) 259.29ms -> clone(arr => Object.assign([], arr));
9) Превышен максимальный размер стека вызовов -> clone(arr => Array.of(...arr));

ОБНОВЛЕНИЯ

  1. Тесты были проведены в 2018 году, поэтому результаты могут отличаться в современных браузерах.
  2. Из этих методов лучший способ глубокого клонирования массива — использование JSON.parse(JSON.stringify(arr)).
  3. Не используйте данный способ, если ваш массив может содержать функции, так как он вернет null. Спасибо @GilEpshtain за это обновление.
0

Для создания "клированного" массива в JavaScript, можно использовать метод concat(), как показано в следующем примере:

var cloned_array = [].concat(target_array);

Этот код создает новый массив cloned_array, который является поверхностной копией массива target_array. Метод concat() объединяет массивы, но если передать в качестве аргумента пустой массив ([]), он просто вернет копию указанного массива. Учтите, что это метод создает лишь поверхностную копию; если в target_array есть вложенные объекты, они будут скопированы по ссылке, а не по значению.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь