V8 выпуск v8.0
Наконец-то это здесь. Каждый выпуск 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% памяти кучи!
При улучшении памяти обычно это происходит за счёт производительности. Обычно. Нам приятно сообщить, что мы наблюдаем улучшения производительности на реальных веб-сайтах во времени, затраченном V8, и во времени его сборщика мусора!
Настольный | Мобильный | ||
---|---|---|---|
Всего (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 и вскоре попробовать новые функции самостоятельно.