Может ли обычный 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, которые, надеюсь, прояснят концепцию:
-
Да, вы можете написать asm.js диалект вручную.
Если вы посмотрите на примеры для asm.js, Они очень далеки от будучи удобный. Очевидно, что Javascript не является языком переднего плана для создания этого кода.
-
перевод ванильного 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. Я не уверен, что это будет практично, но тем не менее это интересная концепция.