Ответ 1
WebAssembly против asm.js
Во-первых, давайте посмотрим, чем, в принципе, WebAssembly отличается от asm.js, и есть ли потенциал для повторного использования существующих знаний и инструментов. Следующее дает довольно хороший обзор:
- Зачем создавать новый стандарт, когда уже есть asm.js?
- В чем разница между asm.js и веб-сборкой?
- Почему WebAssembly быстрее, чем asm.js
Давайте повторим, WebAssembly (MVP, как там больше на его дорожной карте, примерно):
- представляет собой двоичный формат AST со статической типизацией, который может выполняться существующими механизмами JavaScript (и, следовательно, JIT-совместимым или скомпилированным AOT),
- он на 10-20% компактнее (сравнение в сжатом формате) и на порядок быстрее разбирается, чем JavaScript,
- он может выражать более низкоуровневые операции, которые не вписываются в синтаксис JavaScript, читать asm.js (например, 64-разрядные целые числа, специальные инструкции процессора, SIMD и т.д.)
- конвертируемо (до некоторой степени) в/из asm.js.
Таким образом, в настоящее время WebAssembly является итерацией для asm.js и предназначена только для C/C++.
Python в Интернете
Не похоже, что GC - единственное, что мешает коду Python ориентироваться на WebAssembly/asm.js. Оба представляют низкоуровневый статически типизированный код, в котором код Python не может (реально) быть представлен. Поскольку текущий набор инструментов WebAssembly/asm.js основан на LLVM, язык, который можно легко скомпилировать в IR LLVM, можно преобразовать в WebAssembly/asm.js. Но, увы, Python слишком динамичен, чтобы в него вписываться, что доказано Unladen Swallow и несколькими попытками PyPy.
Эта презентация asm.js содержит слайды о состоянии динамических языков. Это означает, что в настоящее время возможно только скомпилировать целую ВМ (языковую реализацию в C/C++) в WebAssembly/asm.js и интерпретировать (с JIT, где это возможно) исходные источники. Для Python существует несколько существующих проектов:
- PyPy: PyPy.js (авторская беседа на PyCon). Здесь релиз репо. Основной файл JS,
pypyjs.vm.js
, составляет 13 МБ (2 МБ послеgzip -6
) + Python stdlib + другие материалы. - CPython: pyodide, EmPython, CPython-Emscripten, EmCPython и т.д.
empython.js
составляет 5,8 МБ (2,1 МБ послеgzip -6
), без stdlib. -
Микропифон: это вилка.
Там не было встроенного файла JS, поэтому я смог собрать его с помощью
trzeci/emscripten/
, готового набора инструментов Emscripten. Что-то вроде:git clone https://github.com/matthewelse/micropython.git cd micropython docker run --rm -it -v $(pwd):/src trzeci/emscripten bash apt-get update && apt-get install -y python3 cd emscripten make -j # to run REPL: npm install && nodejs server.js
Он создает
micropython.js
размером 1,1 МБ (225 КБ послеgzip -d
). Последнее уже нужно учитывать, если вам нужна только очень совместимая реализация без stdlib.Для создания сборки WebAssembly вы можете изменить строку 13
Makefile
наCC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Затем
make -j
производит:113 KB micropython.js 240 KB micropython.wasm
Вы можете посмотреть вывод HTML
emcc hello.c -s WASM=1 -o hello.html
, чтобы увидеть, как использовать эти файлы.Таким образом, вы также можете потенциально собрать PyPy и CPython в WebAssembly для интерпретации вашего приложения Python в совместимом браузере.
Другая потенциально интересная вещь здесь - это Nuitka, компилятор Python to C++. Потенциально можно собрать приложение Python для C++, а затем скомпилировать его вместе с CPython с Emscripten. Но практически я не знаю, как это сделать.
Решения
В настоящее время, если вы создаете обычный веб-сайт или веб-приложение, где скачивание JS файла размером в несколько мегабайт едва ли является опцией, обратите внимание на реализации конвейеров Python-to -j avaScript (например, Transcrypt) или JavaScript Python ( например, Brython). Или попытайте счастья с другими из списка языков, которые компилируются в JavaScript.
В противном случае, если размер загрузки не является проблемой, и вы готовы решить множество неровностей, выберите один из трех вариантов выше.