Может ли обычный JavaScript быть преобразован в asm.js, или это только для ускорения статически типизированных языков низкого уровня?

Я прочитал вопрос Как протестировать и разработать с asm.Яш?, и принятый ответ дает ссылку на http://kripken.github.com/mloc_emscripten_talk/#/.

вывод этого слайд-шоу заключается в том, что"статически типизированные языки и особенно C / C++ могут быть эффективно скомпилированы в JavaScript", так что мы можем"ожидайте, что скорость скомпилированного C / C++ достигнет только 2X медленнее, чем собственный код, или лучше, позже это год".

а насчет номера-статически-типизированные языки, такие как регулярные собственно JavaScript? Может ли он быть скомпилирован в asm.Яш?

7 ответов


может ли JavaScript быть скомпилирован в asm.Яш?

Не очень, из-за его динамической природы. Это та же проблема, что и при попытке ее компиляции С или даже в машинный код - вам действительно нужно будет отправить VM с ним, чтобы позаботиться об этих нестатических аспектах. По крайней мере, такая ВМ возможна:

js.js является интерпретатором JavaScript в JavaScript. Вместо того, чтобы пытаться создайте интерпретатор с нуля,SpiderMonkey составлен в LLVM а то emscripten переводит выходные данные в JavaScript.

но если код asmjs работает быстрее, чем обычный JS, то имеет смысл компилировать JS в asmjs, нет?

нет. asm.js является довольно ограниченным подмножеством JS, которое можно легко перевести в байт-код. Но сначала нужно сломать все расширенные возможности JS для этого подмножества для получения этого преимущества-довольно сложная задача imo. Но движки JavaScript разработаны и оптимизированы для перевода всех этих дополнительных функций напрямую в байт-код - так зачем беспокоиться о промежуточном шаге, таком как asm.Яш? Js.js утверждает, что примерно в 200 раз медленнее, чем" родной " JS.

а насчет номера-статически-типизированные языки вообще?

слайд-шоу говорит об этом от ...Просто C / C++? далее. В частности:

Динамические Языки

все среды выполнения C/C++ могут быть скомпилированы и исходный язык интерпретируется с правильной семантикой, но это не легкий

компиляторы Source-to-source с таких языков на JavaScript игнорируют семантические различия (например, числовые типы)

на самом деле, эти языки зависят от специальных VMs, чтобы быть эффективными

компиляторы Source-to-source для них теряют оптимизацию, выполненную в этих VMs


несколько фактов о asm.js, которые, надеюсь, прояснят концепцию:

  1. Да, вы можете написать asm.js диалект вручную.

    Если вы посмотрите на примеры для asm.js, Они очень далеки от будучи удобный. Очевидно, что Javascript не является языком переднего плана для создания этого кода.

  2. перевод ванильного Javascript в asm.js диалект не возможно.

    подумайте об этом - если вы уже можете перевести стандартный Javascript полностью статически, зачем нужно asm.js? Единственное существование asm.js означает, что люди Javascript JIT у некоторых людей отказались от своего обещания, что Javascript будет быстрее без каких-либо усилий со стороны разработчика.

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

в конце концов, это сводится к использованию правильного инструмента для задачи. Если вам нужен статический, очень эффективный код, используйте C / C++ ( / Java ) - Если вы хотите динамический язык, используйте на JavaScript, Python, ...


в ответ на общий вопрос "это возможно?"тогда ответ таков, что уверен, как JavaScript, так и asm.подмножество js является полным, поэтому существует перевод.

следует ли это делать и ожидать преимущества производительности-это другой вопрос. Короткий ответ: "Нет, вы не должны". Я сравниваю это с попыткой сжать сжатый файл; да, можно запустить алгоритм сжатия, но в целом вы не должны ожидать, что результирующий файл будет меньший.

короткий ответ: стоимость производительности динамически типизированных языков исходит из значения кода; статически типизированная программа с эквивалентным значением будет нести те же расходы.

чтобы понять это, важно понять почему asm.js предлагает преимущество производительности вообще; или, в более общем плане, почему статически типизированные языки работают лучше, чем динамически типизированные. Короткий ответ: "тип времени выполнения проверка требует времени", а более длинный ответ будет включать улучшенную возможность оптимизации статически типизированного кода. Например:

function a(x) { return x + 1; }
function b(x) { return x - 1; }
function c(x, y) { return a(x) + b(y); }

если x и y оба известны как целые числа, я могу оптимизировать функцию c к паре инструкций машинного кода. Если они могут быть целыми числами или строками, задача оптимизации становится намного сложнее; я должен рассматривать их как добавление строки в некоторых случаях и добавление в других случаях. В частности, возможны четыре интерпретации операции сложения, которая происходит в c; это может быть добавление или добавление строки или два разных варианта принуждения к строке и добавлению. По мере добавления возможных типов число возможных перестановок растет; в худшем случае для динамически типизированного языка у вас есть k^n возможные интерпретации выражения с участием n термины, которые могут иметь любое число k типы. На статически типизированном языке, k=1, поэтому всегда существует 1 интерпретация любого данного выражения. Из-за этого оптимизаторы принципиально эффективнее оптимизируют статически типизированный код, чем динамически типизированный: при поиске возможностей оптимизации необходимо учитывать меньше перестановок.

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


asm.js был создан необходимостью иметь небольшое подмножество javascript, которое можно легко оптимизировать. Если у вас есть способ конвертировать javascript в javascript/asm.js, asm.js больше не нужен - этот метод может быть вставлен непосредственно в интерпретаторы js.


теоретически можно преобразовать / скомпилировать / транспилировать любую операцию JavaScript в asm.js, если он может быть выражен с ограниченным подмножеством языка, присутствующего в asm.js. На практике, однако, нет инструмента, способного конвертировать обычный JavaScript в asm.js на данный момент (июнь, 2017).

в любом случае, было бы разумнее преобразовать язык с статическая типизация в asm.js, потому что статическая типизация является требованием asm.js и их отсутствие одна из особенностей обычного JavaScript, что делает его исключительно трудно скомпилировать в asm.js.

назад в 2013 году, когда asm.js был горячим, была попытка скомпилируйте статически типизированный язык, подобный JavaScript, но и язык, и компилятор, похоже, были оставлены.

сегодня, в 2017, JavaScipt подмножества машинопись и поток были бы подходящими кандидатами для преобразования в asm.js, но основной разработчик команды обоих языков не заинтересованы в таком преобразовании. LLJS имел вилку, которая могла компилироваться в asm.JS, но этот проект практически мертв. ThinScript - гораздо более поздняя попытка и основана на TypeScript, но она также не кажется активной.

Итак, лучший и самый простой способ производства asm.JS код еще писать код на C/C++ и сконвертировать / скомпилировать / transpile его. Однако еще предстоит выяснить, захотим ли мы вообще это сделать. это в обозримом будущем. Веб-Сборке может скоро заменить asm.js в целом, и уже появляются машинописные языки, такие как TurboScript и AssemblyScript которые преобразуются в веб-сборку. Фактически, TurboScript изначально был основан на ThinScript и использовался для компиляции в asm.js, но они, похоже, отказались от этой функции.


проверьте это http://badassjs.com/post/43420901994/asm-js-a-low-level-highly-optimizable-subset-of

в основном вам нужно проверить, что ваш код будет asm.js совместимость (нет принуждения или типа литья, вам нужно управлять памятью и т. д.). Идея этого-написать свой код на javascript, обнаружить горлышко бутылки и внести изменения в свой код для использования asm.JS и компиляция aot вместо jit и динамической компиляции...немного Пита, но вы можете все еще используйте javascript или другие языки, такие как C++ или лучше..в ближайшем будущем, lljs.....


возможно преобразование обычного JavaScript в ams.js by first компиляции в C или C++, а затем компиляция сгенерированного кода в asm.Яш, используя Emscripten. Я не уверен, что это будет практично, но тем не менее это интересная концепция.