V8 выпуск v7.6
Каждые шесть недель мы создаём новую ветку V8 в рамках нашего процесса выпуска. Каждая версия создаётся из главной ветки Git V8 непосредственно перед этапом Beta Chrome. Сегодня мы рады объявить о создании нашей новой ветки, V8 версии 7.6, которая будет находиться в бета-версии до её выпуска вместе со стабильной версией Chrome 76 через несколько недель. V8 v7.6 наполнен разнообразными обновлениями для разработчиков. В этом посте представлен предварительный обзор некоторых из основных изменений перед официальным выпуском.
Производительность (размер и скорость)
Улучшения в JSON.parse
В современных JavaScript-приложениях JSON обычно используется как формат для передачи структурированных данных. Ускорив обработку JSON, мы можем уменьшить задержку при этой передаче данных. В V8 v7.6 мы существенно переработали наш JSON-парсер, сделав его намного быстрее при сканировании и разборе JSON. Это привело к увеличению скорости обработки данных, предоставляемых популярными веб-страницами, до 2.7×.
До V8 v7.5 JSON-парсер был рекурсивным и использовал пространство стека, зависящее от глубины вложения входящих JSON-данных, что могло повлечь за собой переполнение стека при обработке сильно вложенных JSON-данных. V8 v7.6 переходит к итеративному парсеру, который управляет своим собственным стеком и ограничен только доступной памятью.
Новый JSON-парсер также более эффективно использует память. Буферизуя свойства перед созданием окончательного объекта, теперь мы можем определить, как оптимально распределить результат. Для объектов с именованными свойствами мы выделяем память с точным количеством пространства, необходимого для свойств, указанных во входных данных JSON (до 128 именованных свойств). Если JSON-объекты содержат индексированные имена свойств, мы выделяем хранилище элементов, использующее минимально необходимое пространство: либо плоский массив, либо словарь. JSON-массивы теперь обрабатываются в массив, который точно соответствует количеству элементов во входных данных.
Улучшения замороженных/запечатанных массивов
Производительность вызовов на замороженных или запечатанных массивах (и объектах, похожих на массивы) получила множество улучшений. V8 v7.6 ускоряет следующие шаблоны JavaScript-кода, где frozen
— это замороженный или запечатанный массив или объект, похожий на массив:
frozen.indexOf(v)
frozen.includes(v)
- вызовы с оператором распространения, такие как
fn(...frozen)
- вызовы с вложенной конструкцией распространения массива, такие как
fn(...[...frozen])
- вызовы
apply
с распространением массива, такие какfn.apply(this, [...frozen])
График ниже показывает улучшения.
См. документацию «быстрые замороженные и запечатанные элементы в V8» для получения подробной информации.
Обработка строк Unicode
Оптимизация при преобразовании строк в Unicode привела к значительному ускорению вызовов, таких как String#localeCompare
, String#normalize
и некоторых из API Intl
. Например, это изменение увеличило пропускную способность String#localeCompare
приблизительно в 2 раза для строк в одну байту.
Особенности языка JavaScript
Promise.allSettled
Promise.allSettled(promises)
предоставляет сигнал, когда все входные промисы выполнены, то есть они либо исполнены, либо отклонены. Это полезно в случаях, когда состояние промиса не важно, но необходимо знать, когда работа завершена, независимо от того, была ли она успешной. Наш объяснитель о promise-комбинаторах содержит более подробную информацию и включает пример.
Улучшенная поддержка BigInt
BigInt
теперь имеет лучшую поддержку API в языке. Теперь вы можете форматировать BigInt
с учетом локали, используя метод toLocaleString
. Это работает так же, как для обычных чисел:
12345678901234567890n.toLocaleString('en'); // 🐌
// → '12,345,678,901,234,567,890'
12345678901234567890n.toLocaleString('de'); // 🐌
// → '12.345.678.901.234.567.890'
Если вы планируете форматировать несколько чисел или BigInt
, используя одну и ту же локаль, более эффективно использовать API Intl.NumberFormat
, который теперь поддерживает BigInt
в своих методах format
и formatToParts
. Таким образом, вы можете создать единый переиспользуемый экземпляр форматировщика.
const nf = new Intl.NumberFormat('fr');
nf.format(12345678901234567890n); // 🚀
// → '12 345 678 901 234 567 890'
nf.formatToParts(123456n); // 🚀
// → [
// → { type: 'integer', value: '123' },
// → { type: 'group', value: ' ' },
// → { type: 'integer', value: '456' }
// → ]
Улучшения Intl.DateTimeFormat
Приложения часто отображают интервалы или диапазоны дат, чтобы показать продолжительность события, такого как бронь в гостинице, расчетный период услуги или музыкальный фестиваль. API Intl.DateTimeFormat
теперь поддерживает методы formatRange
и formatRangeToParts
для удобного форматирования диапазонов дат с учетом локализации.
const start = new Date('2019-05-07T09:20:00');
// → '7 мая 2019 г.'
const end = new Date('2019-05-09T16:00:00');
// → '9 мая 2019 г.'
const fmt = new Intl.DateTimeFormat('ru', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
const output = fmt.formatRange(start, end);
// → '7 – 9 мая 2019 г.'
const parts = fmt.formatRangeToParts(start, end);
// → [
// → { 'type': 'month', 'value': 'май', 'source': 'shared' },
// → { 'type': 'literal', 'value': ' ', 'source': 'shared' },
// → { 'type': 'day', 'value': '7', 'source': 'startRange' },
// → { 'type': 'literal', 'value': ' – ', 'source': 'shared' },
// → { 'type': 'day', 'value': '9', 'source': 'endRange' },
// → { 'type': 'literal', 'value': ', ', 'source': 'shared' },
// → { 'type': 'year', 'value': '2019', 'source': 'shared' },
// → ]
Кроме того, методы format
, formatToParts
и formatRangeToParts
теперь поддерживают новые параметры timeStyle
и dateStyle
:
const dtf = new Intl.DateTimeFormat('ru', {
timeStyle: 'medium',
dateStyle: 'short'
});
dtf.format(Date.now());
// → '19.06.19, 13:33:37'
Нативный просмотр стэка
Хотя V8 может анализировать собственный стек вызовов (например, при отладке или профилировании в DevTools), операционная система Windows не могла анализировать стек вызовов, содержащий код, сгенерированный TurboFan, при работе на архитектуре x64. Это могло приводить к поломкам стэков при использовании нативных дебаггеров или ETW-сэмплинга для анализа процессов, использующих V8. Недавнее изменение позволяет V8 регистрировать необходимую метаинформацию для Windows для анализа этих стэков на x64, и в версии 7.6 это включено по умолчанию.
API V8
Используйте git log branch-heads/7.5..branch-heads/7.6 include/v8.h
, чтобы получить список изменений API.
Разработчики с активной копией V8 могут использовать git checkout -b 7.6 -t branch-heads/7.6
, чтобы протестировать новые функции в V8 версии 7.6. Также вы можете подписаться на Beta-канал Chrome и скоро попробовать новые функции самостоятельно.