WeakMap в Javascript

Недавно я злоупотреблял WeakMap для решения проблем производительности в Javascript.
WeakMap работает очень похоже на своего более сильного брата Map. Вы предоставляете ключ и значение. Когда вам нужно получить значение для этого ключа, вы можете получить его из WeakMap.
Разница между Map и WeakMap в том, что последняя не хранит ссылку на ключ, если сборщику мусора понадобится очистить его из памяти, WeakMap скажет, что все в порядке, ключ и значение будут очищены одновременно.

Кэширование

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

Мы можем реализовать функцию более высокого порядка под названием weakMemoize, которая украсит нашу функцию слоем кэширования с помощью WeakMap.

function weakMemoize(toDecorate) {
  const cache = new WeakMap()
  return function (value) {
    if (!cache.has(value)) {
      cache.set(value, toDecorate(value))
    }
    return cache.get(value)
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Затем мы можем использовать для кэширования наши функции

const getKeys = weakMemoize((value) => {
    return Object.keys(value)
})

const obj = { a: 10, b: 20, c: 30 }

getKeys(obj)
// second time the value is read from the cache.
getKeys(obj)
Войти в полноэкранный режим Выход из полноэкранного режима

Я не беспокоюсь о потреблении памяти, поскольку всякий раз, когда obj или getKeys выходят из области видимости, сборщик мусора также будет собирать значения в карте. Я избегаю выполнения Object.keys во второй раз без дополнительных сложностей в реализации моей функции.

Соображения

Следует принять во внимание несколько моментов. Ключом WeakMap может быть только объект (object или Array), мы не можем использовать примитивное значение в качестве ключа.
Другое соображение заключается в том, что если у вас есть долгоживущие объекты, кэширование подобных вещей может быть не очень выгодным, много объектов будет оставаться в памяти, подумайте об использовании LRU кэша.

Также, вам не нужно реализовывать свой собственный weakMemoize, есть хорошие реализации в npm.

Спасибо за прочтение!
Увидели проблему в моем посте? Пожалуйста, прокомментируйте или свяжитесь со мной в twitter.

Оцените статью
devanswers.ru
Добавить комментарий