Monomorphic / Polymorphic / Megamorphic
Три состояния inline-кэша функции — определяют, как быстро V8 обращается к свойствам объекта. Главное правило для горячего кода: сохраняй мономорфность.
Состояния
| Состояние | Форм объекта | Стоимость доступа |
|---|---|---|
| Monomorphic | 1 | прямой оффсет, ~1 инструкция |
| Polymorphic | 2-4 | проверка по списку форм |
| Megamorphic | 5+ | глобальный hashmap по имени свойства |
Деградация по примеру
function getX(o) { return o.x; }
getX({ x: 1 }); // monomorphic
getX({ x: 1, y: 2 }); // polymorphic (2)
getX({ a: 0, x: 1 }); // polymorphic (3)
getX({ a: 0, b: 0, x: 1 }); // polymorphic (4)
getX({ a: 0, b: 0, c: 0, x: 1 }); // MEGAMORPHIC
Inline-кэш локален к функции
Состояние накапливается в каждой функции отдельно. Один и тот же объект, проходя через разные функции, в каждой имеет свой IC.
Полиморфизм касается не только свойств
- Свойства объектов
- Методы (
o.toString()) - Элементы массива (SMI / Double / Object / packed / holey)
Как держать monomorphic
- Инициализируй все поля в конструкторе, в одном порядке.
- Не делай
deleteна свойствах. - Не подсовывай в горячую функцию объекты разных классов.
- Для разных форм пиши разные специализированные функции.
Источники
- Мономорфный и полиморфный код, inline-кэш · 2019-10-29
- Тезисы: 4 формы — ещё полиморфно; 5-я форма — мегаморф, переход в глобальный кэш V8
- Цитата: «Мегаморфного кэша, который глобальный вообще для всего джаваскрипта, для всего рантайма.»
- Производительность V8 объектов в примерах · AsForJS · 2025-02-11