Самый эффективный способ скопировать карту в существующую карту

#javascript #dictionary #ecmascript-6 #clone

#javascript #словарь #ecmascript-6 #клонировать

Вопрос:

Я хочу перезаписать Map b во фрагменте ниже содержимым Map a. В настоящее время я очищаю содержимое b, а затем устанавливаю записи одну за другой. Какой более эффективный способ (меньше мусора, быстрее и т.д.) Написания copyMap функции?

 const a = new Map([[1, 2], [2, 10], [3, 20]]);
const b = new Map([[1,5]]);

// I want to copy a into b, at the end b should look like
// b = new Map([[1, 2], [2, 10], [3, 20]]);

console.log(a,b);

function copyMap(srcMap, destMap) {
  destMap.clear();
  
  // Maybe this loop could be done in a single call somehow?
  for(let item of srcMap) {
    destMap.set(item[0], item[1]);
  }
}
copyMap(a, b);

// a and b should have same entries
console.log('a: ',[...a.entries()], 'b: ', [...b.entries()]);  

Комментарии:

1. Я не думаю, что copyMap могло быть проще того, что вы сделали. (Возможно, используйте деструктурирование для item , но это всего лишь синтаксис).

2. Моя главная цель — уменьшить генерацию мусора, как это делается для высокопроизводительного приложения, где паузы GC могут испортить работу пользователя, и я хочу повторно использовать как можно больше уже созданных объектов. Я действительно думаю (исходя из предыдущего опыта), что изменение существующего объекта происходит быстрее и генерирует меньше мусора, чем создание нового.

3. Нет, Map у s нет метода массового копирования. Единственный метод, который принимает iterable, — это конструктор. Я не думаю, что он предварительно выделяет память до ожидаемого размера, но вы все равно можете попытаться сделать b = new Map(a) .

4. У меня есть несколько экземпляров приложения (десятки или сотни), работающих со скоростью 60 кадров в секунду в одном потоке, каждые несколько кадров принимается новое a сообщение (разное для каждого экземпляра), и я должен сохранить его / скопировать в b . В моем конкретном случае оба a и b имеют (в основном) одинаковые ключи (но разные значения для этих ключей) при каждом использовании функции копирования, поэтому, вероятно, лучше не очищать карту раньше, а только устанавливать / перезаписывать текущие ключи.

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

Ответ №1:

вы можете просто сделать

 b=new Map(a)
  

и вам нужно потерять объявление const для b

Комментарии:

1. Но таким образом предыдущий b Map станет мусором, а я хочу избежать создания мусора.

2. тогда почему бы не скопировать ее в новую переменную?

3. Что вы имеете в виду, я только что объяснил выше? Я выполняю copyMap операцию сотни раз в секунду, если я создаю new Map каждый раз, это приведет к большому распределению и созданию большого количества мусора.

4. Смотрите раздел Управление памятью , чтобы лучше понять проблему сборки мусора, которую OP пытается решить здесь.