Перейти к основному содержимому

V8 выпуск v8.0

· 5 мин. чтения
Лешек Свирски, V8-ой по счёту

Наконец-то это здесь. Каждый выпуск V8, каждые шесть недель, когда мы делаем ветку согласно нашему процессу выпуска, возникает вопрос о том, что произойдет, когда V8 достигнет версии 8. Будет ли вечеринка? Выпустим ли мы новый компилятор? Пропустим ли версии 8 и 9 и останемся на вечной версии V8 Х? Наконец, после более 10 лет работы, в нашем 100-м посте в блоге, мы рады объявить о нашей новой ветке, V8 version 8.0 V8, и наконец можем ответить на этот вопрос:

Это исправления ошибок и улучшения производительности.

В этом посте представлен предварительный обзор некоторых основных моментов в преддверии выпуска, согласованного с Chrome 80 Stable через несколько недель.

Производительность (размер и скорость)

Сжатие указателей

Мы изменили все наши void * на pv, уменьшив размер исходного файла до 66%.

Куча V8 содержит множество элементов, например, значения с плавающей точкой, символы строк, скомпилированный код и маркированные значения (которые представляют собой указатели в куче V8 или маленькие целые числа). При проверке кучи мы обнаружили, что эти маркированные значения занимают большую часть кучи!

Маркированные значения так же велики, как системный указатель: они имеют ширину 32 бита для 32-битных архитектур и 64 бита для 64-битных архитектур. Затем, сравнивая 32-битную версию с 64-битной, мы используем в два раза больше памяти кучи для каждого маркированного значения.

К счастью для нас, у нас есть трюк в рукаве. Старшие биты могут быть синтезированы из младших битов. Затем нам нужно только хранить уникальные младшие биты в куче, экономя ценные ресурсы памяти... экономя в среднем 40% памяти кучи!

Сжатие указателей экономит в среднем 40% памяти.

При улучшении памяти обычно это происходит за счёт производительности. Обычно. Нам приятно сообщить, что мы наблюдаем улучшения производительности на реальных веб-сайтах во времени, затраченном V8, и во времени его сборщика мусора!

НастольныйМобильный
FacebookВсего (V8)-8%-6%
^^GC-10%-17%
CNNВсего (V8)-3%-8%
^^GC-14%-20%
Карты GoogleВсего (V8)-4%-6%
^^GC-7%-12%

Если сжатие указателей вызвало ваш интерес, следите за полной публикацией в блоге с более подробной информацией.

Оптимизация встроенных функций высшего порядка

Недавно мы устранили ограничение в конвейере оптимизации TurboFan, которое препятствовало активным оптимизациям встроенных функций высшего порядка.

const charCodeAt = Function.prototype.call.bind(String.prototype.charCodeAt);

charCodeAt(string, 8);

До сих пор вызов charCodeAt был полностью непрозрачным для TurboFan, что приводило к созданию общего вызова пользовательской функции. Благодаря этому изменению мы теперь можем распознать, что на самом деле вызываем встроенную функцию String.prototype.charCodeAt, и, таким образом, можем активировать все дальнейшие оптимизации, которые TurboFan имеет в своем арсенале для улучшения вызовов встроенных функций, что приводит к той же производительности, как:

string.charCodeAt(8);

Это изменение затрагивает множество других встроенных функций, таких как Function.prototype.apply, Reflect.apply, и многие встроенные функции высшего порядка для массивов (например, Array.prototype.map).

JavaScript

Опциональные цепочки

При написании цепочек доступа к свойствам программистам часто приходится проверять, не являются ли промежуточные значения nullish (то есть null или undefined). Цепочка без проверки на ошибки может привести к исключению, а цепочка с явной проверкой ошибок является многословной и имеет нежелательное последствие проверки всех истинных значений вместо только non-nullish значений.

// Ошибочная версия, может вызвать исключение.
const nameLength = db.user.name.length;

// Менее подвержена ошибкам, но менее читаема.
let nameLength;
if (db && db.user && db.user.name) nameLength = db.user.name.length;

Опциональные цепочки (?.) позволяют программистам писать краткие, надёжные цепочки доступа к свойствам, которые проверяют, являются ли промежуточные значения nullish. Если промежуточное значение является nullish, то всё выражение оценивается как undefined.

// Всё ещё проверяет ошибки и гораздо более читаемо.
const nameLength = db?.user?.name?.length;

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

Оператор nullish coalescing

Оператор nullish coalescing ?? — это новый бинарный оператор короткого замыкания для обработки значений по умолчанию. В настоящее время значения по умолчанию иногда обрабатываются с использованием логического оператора ||, как в следующем примере.

function Component(props) {
const enable = props.enabled || true;
// …
}

Использование || нежелательно для вычисления значений по умолчанию, поскольку a || b принимает значение b, если a является ложным. Если props.enabled было явно установлено в false, enable все равно будет равен true.

С оператором nullish coalescing a ?? b принимает значение b, если a имеет значение nullish (null или undefined), в противном случае принимается значение a. Это желательная реализация поведения значений по умолчанию, и переписывая пример с использованием ??, устраняется ошибка, указанная выше.

function Component(props) {
const enable = props.enabled ?? true;
// …
}

Оператор nullish coalescing и оператор optional chaining являются сопутствующими функциями и работают хорошо вместе. Пример может быть дополнительно изменен для обработки случая, когда аргумент props не передан.

function Component(props) {
const enable = props?.enabled ?? true;
// …
}

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

API V8

Используйте команду git log branch-heads/7.9..branch-heads/8.0 include/v8.h, чтобы получить список изменений в API.

Разработчики с актуальной копией исходного кода V8 могут использовать команду git checkout -b 8.0 -t branch-heads/8.0, чтобы поэкспериментировать с новыми функциями в V8 версии 8.0. Кроме того, вы можете подписаться на бета-канал Chrome и вскоре попробовать новые функции самостоятельно.