Pull to refresh

Comments 9

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

И хотел бы указать на ошибку:
Проблема в том, что байткод сейчас разный. Как я уже сказал: в Safari один, в FireFox другой, в Chrome третий. Тем не менее разработчики из Mozilla, Bloomberg и Facebook выдвинули такой Proposal, но это будущее.


Это предложение не имеет отношения к внутреннему байткоду браузеров, наоборот, это просто упрощённое (для парсинга движками) представление того же самого JavaScript. У этого предложения нет целей заменить внутренний байткод движков, нет целей уменьшить доставляемый пользователю объём кода, есть лишь только цель ускорить начальный парсинг (ценой некоторых дополнительных телодвижений на этапе сборки).

Начинал переводить это предложение год назад, сразу после его появления в TC39, но по разным причинам до публикации этот перевод не добрался (в первую очередь я в итоге посчитал, что это будет скучно и мало смысла имеет для конечных разработчиков).

Но чтобы подтвердить свои слова про ошибку, вставлю маленькую часть этого перевода (это FAQ, в самом конце основного readme предложения):

Почему бы не использовать байткод вместо вашего предложения?

В вебе ни один из вендоров не захочет реализовывать сторонний байткод:

  • Движки не хотят зависеть от версий байткода
  • Проверять байткод сложнее, так как он более выразительный, чем [JS] синтаксис
  • Так как байткод более выразительный, чем JavaScript, появится риск разветвления развития языка
  • Создание нового байткода — это намного более амбициозная задача [чем наше предложение бинарного AST]

Не будет ли проблем с поддержкой нового формата?

Парсинг бинарного AST будет проще, чем парсинг существующего JavaScript. Это несомненно увеличит сложность реализации (браузеров), но мы считаем, что это меньшее из двух зол, учитывая тренд возрастания сложности и размера веб-приложений.

Не будет ли распухать размер конечного файла?

В нашем прототипе [ранее в статье] мы выяснили, что AST формат занимает чуть-чуть меньше места, даже если сравнивать с минифицированным тестовым JS.


Это предложение больше похоже на промежуточный универсальный формат, чтобы стандартизировать парсинг кода не только браузерам, но и всяким flowtype, eslint, jest, jsdoc, <ваш вариант>. Сейчас все эти инструменты сами парсят исходный код (используя разные парсеры, кто во что горазд), но если babel во время разработки будет на лету преобразовывать исходный код в binary AST, который затем уйдёт в браузер (как обновление в рамках hot module replacement) и он же уйдёт в flowtype, eslint, jsdoc и так далее, позволяя последним не включать в свой код какие-либо парсеры, а сразу перейти к шагу обработки AST своими трансформерами, то всем будет намного проще. Разработчикам (которые конечные пользователи всего этого) в первую очередь — так как исчезнет зоопарк разных настроек для парсеров в разных инструментах и уменьшится потребление ресурсов для вывода нотификаций.

Конечно тогда все должны использовать трансформеры, работающие со стандартизированным форматом AST, а такие вещи, как esprima/acorn и babel/parser (бывший babylon) должны уметь генерировать этот самый стандартизированный AST, и преодолеть различия между своими форматами.

Собственно для перехода на новый формат AST вместо estree-совместимого был сделан issue github.com/babel/proposals/issues/21 год назад. Но, как и в самом proposal, за прошедший год там нет никаких телодвижений :(
Загадка: new Array(1000) vs array = []
Правильный ответ: зависит от.
Когда мы создаем массив первым способом и заполняем 1000 элементов, мы создаем 1000 дырок. Этот массив не будет оптимизирован. Но в него будет быстро писать.
Создавая массив по второму варианту, выделяется немного памяти, мы записываем, например, 60 элементов, выделяется еще немного памяти, и т.д. То есть в первом случае быстро пишем — медленно работаем; во втором медленно пишем — быстро работаем.

интересный ответ. накидал тест: https://jsperf.com/arrrray
в этом тесте производительность зависит исключительно от движка. в последних версиях firefox и chrome, Array(1500) всегда быстрее, чем []. а в последней версии edge (разумеется :) наоборот. но статья ведь о v8, а не chakra.
почему результат моего теста не совпадает со статьей?
UFO just landed and posted this here
добавил два теста на чтение (sparse 1 50 и empty 1 50): https://jsperf.com/arrrray
оба варианта стали примерно одинаковыми по скорости, так что один хрен результат со статьей не совпадает.
UFO just landed and posted this here

А можно пример. Как не кручу, а hole-массив замедлить не удаётся.


Вот, скажем, быстрый пример от руки:
var limit = 1000000;

console.time('push');
var arr = [];
for(var i = 0; i < limit; ++ i)
  arr.push(i);
console.log('sum', arr.reduce((sum, n) => sum + n, 0));
console.timeEnd('push');

console.time('holes');
var arr = new Array(limit);
for(var i = limit - 1; i >= 0; -- i)
  arr[i] = i;
console.log('sum', arr.reduce((sum, n) => sum + n, 0));
console.timeEnd('holes')

И ничего. Если вынести создание и заполнение массивов за границы — holes всё равно оказывается быстрее. Я, как вы можете видеть, даже попытался обмануть v8 и заполнить псевдо-дырявый массив с конца. Даже arr[999999999999] = true; ничего не меняет, хотя казалось бы куда уж хуже.


Почему так? Должно же тормозить.

Получается, что если условный SpiderMonkey будет нативно поддерживать TypeScript, либо любую другую типизированную надстройку над ECMAScript, то байткод в нём будет лучше оптимизирован и, как следствие будет быстрее работать.

Ссылка на видео доклада:


Sign up to leave a comment.