Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Слайд-шоу рассказывает об этом от ... Только C/С++? и далее. В частности:

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

     

Можно выполнить компиляцию целых C/С++ и исходный язык   интерпретируется с помощью правильной семантики, но это нелегко

     

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

     

Фактически, эти языки зависят от специальных виртуальных машин, чтобы быть эффективными

     

Исходные компиляторы для них теряют оптимизацию, выполняемую в этих виртуальных машинах.

Ответ 2

В ответ на общий вопрос "возможно ли это?" то ответ будет уверен, что и 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; это может быть добавление или добавление строки или два разных варианта coerce-to-string-and-append. Когда вы добавляете более возможные типы, число возможных перестановок возрастает; в худшем случае для динамически типизированного языка у вас есть возможные интерпретации выражения, содержащего n терминов, каждый из которых может иметь любое число k типов. В статически типизированном языке k = 1, поэтому всегда имеется 1 интерпретация любого данного выражения. Из-за этого оптимизаторы существенно более эффективны при оптимизации статически типизированного кода, чем динамически типизированный код: при поиске возможностей для оптимизации требуется меньше перестановок.

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

Ответ 3

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

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

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

  • Перевод ванили Javascript на диалект asm.js не.

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

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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

Ответ 6

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

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

Ответ 7

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

Совсем недавно я нашел другой инструмент под названием NectarJS, который компилирует JavaScript в WebAssembly и ASM.js.