Плюсы и минусы "режима словаря"

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

Пример:

var user = { name: 'connor', sex: 'male' }; 
// user is in "fast mode"

delete user.sex;
// user is in ("slow" or "dictionary") mode 

Когда это может быть полезно и когда это может быть вредным?

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

Также существует ли какая-либо семантика вокруг этого режима?

Ответ 1

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

Это не вещь JavaScript; это реализация, характерная для двигателя V8 внутри Chrome. Этот поток в списке пользователей V8 обсуждает это:

[ZenWolf]... Использует ли JavaScript "удалить" ключевое слово, чтобы удалить свойство из эффекта объекта (sic), как v8 будет оптимизировать объект?...

[Sven Panne]... Удаление свойства приводит к переходу в "медленный режим", т.е. с использованием словаря для свойств объекта. Так как общее правило, использование "delete" делает вещь медленнее...

Этот эффект можно увидеть в этом JSPerf. Обратите внимание, что браузеры, использующие V8 (Chrome, Opera 20), медленнее с delete, чем без него. Firefox последний SpiderMonkey ослепительно быстрый в любом случае, IE10 и 11 слегка влияют. (Интересно, что двигатель Opera, использующийся для 10.5-12 [кажется, это был], Каракан, был еще сильнее затронут delete, чем V8.)

Если вы пишете код, который будет использоваться в веб-браузерах, оптимизация для конкретного движка, как правило, является пустой тратой времени, если вы не сталкиваетесь с конкретной проблемой производительности в реальном мире на этом движке. (И если вы, как только вы это делаете, убедитесь, что эти изменения не испортили другие движки!)

Если вы писали для NodeJS, SilkJS и т.д., то, конечно, оптимизация для V8 в порядке (хотя нормальные правила преждевременной оптимизации все еще применяются), поскольку они специально созданы для V8.

Также существует ли какая-либо семантика вокруг этого режима?

Нет. Семантика JavaScript определяется спецификацией, которая не диктует, как реализуются объекты, если их поведение соответствует семантике spec; спецификация вообще не затрагивает производительность. V8 реализует объекты, создавая динамические классы "на лету" и компилируя их в машинный код, но при возврате в них "медленных" (словарных) режимов возвращается обратно. (Если вы добавляете свойства, гораздо более распространенная операция, как сказал Свен Панн в приведенной выше цитате, она динамически создает производный класс, который не замедляет работу). Но другие двигатели могут реализовать их как хэш-карты или связанные списки свойств или что-то еще.

Ответ 2

Удалить делает вещи медленнее, да, но это будет еще медленнее, если V8 попытается сохранить объект в быстром режиме, даже когда вы меняете свою форму все время. Объекты должны иметь фиксированный набор свойств, чтобы их можно было статически загружать с фиксированными смещениями (подобно полям объектов С++ или Java). Если вы произвольно удаляете и добавляете свойства (I.E. меняя форму объекта), эта статическая загрузка при фиксированных смещениях не может быть выполнена.

Итак, это в основном очень чувствительная эвристика: если вы вызываете delete даже один раз, V8 предполагает, что вы собираетесь менять форму объекта даже в будущем и отказываться от него - даже если на самом деле вы только назовете delete только один раз и после этого форма не изменится.

Преимущество в том, что выполнение поиска хэш-таблицы намного быстрее, чем повторное вычисление скрытого класса (и повторная компиляция всех функций на основе старого скрытого класса) каждый раз при изменении формы.

Ответ 3

в этой статье есть несколько ответов о том, как Google v8 обрабатывает свойства объекта

статья подтверждает, что существуют такие вещи, как медленные и быстрые свойства

Я предполагаю, что если имена ваших свойств часто меняются, лучше всего использовать "Карту".

https://v8.dev/blog/fast-properties