Прежде чем перейти к советам по оптимизации производительности, давайте обсудим, что такое V8?

V8 - это высокопроизводительный движок Javascript с открытым исходным кодом, созданный Ларсом Баком (датский программист, работающий в настоящее время в Google).
* Он был написан на C ++ и использовался в больших проектах, таких как Couchbase, Node.js и т. Д.
* Он реализует ECMAScript (ECMA-262)
* Он стал самым известным Механизм Javascript, поскольку основные различия между V8 и другими механизмами Javascript заключаются в том, что V8 не создает байт-код или промежуточный код. Он напрямую компилирует код Javascript в собственный машинный код перед его выполнением.
* Он состоит из Ignition интерпретатор и TurboFan (оптимизирующий компилятор), что делает V8 КОРОЛЕМ

Javascript не имеет явных типов, поэтому немного сложно улучшить производительность, потому что быстрый сбор информации о типах затруднен во время процесса компиляции, потому что для Javascript компиляция является частью выполнения. Поэтому нам нужно найти способы улучшить это. Однако есть некоторые хитрости.

Скрытый класс

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

V8 внутренне создает основные скрытые классы для объектов во время выполнения.
Объекты с одним и тем же скрытым классом могут использовать один и тот же оптимизированный сгенерированный код

Для каждого нового добавленного свойства V8 создает новый скрытый класс, сохраняя старый класс для справки.

После добавления нового свойства будет создан новый класс из Person
[name, age, salary] // Теперь ссылки на person1 и person2 будут изменены на этот новый класс. Из-за этого предположения о встроенном кэшировании (IC) изменятся (т.е. оптимизированный сгенерированный код необходимо повторно оптимизировать)

Методы повышения производительности:

* Для каждого нового свойства, добавляемого к существующему объекту, V8 создает новый скрытый класс, поэтому для повышения производительности Javascript мы можем прекратить добавление нового свойства после создания объекта.

* Инициализировать все члены объекта в функциях конструктора

* Всегда инициализируйте элементы объекта в одном и том же порядке

Массивы

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

Методы повышения производительности:

* Используйте непрерывные ключи, начиная с 0 для массивов.

* Не выделяйте заранее большие массивы (›64 КБ элементов), пусть они растут по мере вашего продвижения.

* Удаление элементов из массива увеличивает производительность. (Не удаляйте элементы в массивах)

* Избегайте загрузки неинициализированных или удаленных элементов.

Пример

Но массивы двойников работают медленно из-за тегов
1. Скрытый класс массивов отслеживает типы элементов.
2. Массивы, содержащие только двойники, распаковываются.
3. Причины распаковки: скрыл изменение класса. Таким образом, неосторожное умножение Array может вызвать дополнительную работу из-за упаковки и распаковки.

Скрытые классы для элементов - впереди проблемы

Методы повышения производительности:

* Инициализация с использованием литералов массива для небольших массивов фиксированного размера.

* Предварительно выделите небольшие массивы для правильного размера перед их использованием.

* Не храните нечисловые значения (объекты) в числовых массивах.

Компиляторы

V8 имеет два компилятора
1. Полный компилятор (базовый уровень)
2. Оптимизирующий компилятор

1. Полный компилятор. Он может генерировать хороший код для любого Javascript, но не лучший JIT-код. Его цель - быстро сгенерировать код. Для достижения цели он не выполняет никаких анализов и ничего не знает о типах. Он использует встроенные кеши (IC) для уточнения информации о типах во время работы программы и увеличивает скорость в 20 раз.

IC эффективно обрабатывает типы
- Код, зависящий от типа, для операций.
- Сначала проверяйте предположения о типах, а затем выполняйте работу.
- Изменяйте во время выполнения с помощью обратного исправления по мере обнаружения новых типов.

Мономорфный всегда лучше полиморфного

Если скрытые классы всегда одни и те же, то они мономорфны, если не полиморфны.

2. Оптимизирующий компилятор. Это создает отличный код. Он появляется позже и перекомпилирует горячие функции. Он использует IC (встроенный кеш), чтобы знать о типах и принимать решения о том, как лучше оптимизировать код.

Небольшие изменения имеют большое значение

Теперь давайте немного изменим наш алгоритм.

Видите ли, мы можем улучшить скорость выполнения Javascript с помощью небольшого изменения нашего алгоритма - Оптимизируйте алгоритм Javascript.

Методы повышения производительности:

* V8 также поддерживает деоптимизацию: оптимизирующий компилятор делает оптимистические предположения из встроенного кеша, но иногда может давать сбой, поэтому в этих случаях V8 отбрасывает оптимизированный код и возвращается к полному компилятору, чтобы снова получить типы из IC. Этот процесс является медленным, и его следует избегать, стараясь не изменять функции после их оптимизации.

Это несколько советов по повышению производительности Javascript, мы можем углубиться в V8, чтобы получить больше информации.

Ресурс
Слайды Дэниела Клиффорда, технического руководителя и менеджера группы V8