WebAssembly против 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 в сети
Не похоже, что сборщик мусора - единственное, что мешает коду Python нацеливаться на WebAssembly / asm.js. Оба представляют собой низкоуровневый статически типизированный код, в котором код Python не может (реалистично) быть представлен. Поскольку текущий набор инструментов WebAssembly / asm.js основан на LLVM, язык, который можно легко скомпилировать в LLVM IR, можно преобразовать в WebAssembly / asm.js. Но, увы, Python слишком динамичен, чтобы вписаться в него, что было доказано Unladen Swallow и несколькими попытками PyPy.
В этой презентации asm.js есть слайды о состоянии динамических языков . Это означает, что в настоящее время можно скомпилировать только виртуальную машину целиком (языковая реализация на C / C ++) в WebAssembly / asm.js и интерпретировать (при возможности с JIT) исходные коды. Для Python существует несколько существующих проектов:
PyPy: PyPy.js ( доклад автора на PyCon ). Вот репо релиза . Основной JS-файл pypyjs.vm.js
имеет gzip -6
размер 13 МБ (после 2 МБ ) + Python stdlib + другие вещи.
CPython: pyodide , EmPython , CPython-Emscripten , EmCPython и т. Д. Составляетempython.js
5,8 МБ (после 2,1 МБ gzip -6
), stdlib отсутствует.
Micropython: эта вилка .
Там не было встроенного файла 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
Выдает 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 в C ++. Потенциально можно создать приложение Python на C ++, а затем скомпилировать его вместе с CPython с помощью Emscripten. Но практически не знаю, как это сделать.
Решения
За время, если вы создаете обычный веб - сайт или веб - приложение , где скачать несколько мегабайт JS файл является едва ли вариант, посмотрите на Python-к-JavaScript transpilers (например Transcrypt ) или реализации JavaScript Python (например бритт ). Или испытайте удачу с другими из списка языков, которые компилируются в JavaScript .
В противном случае, если размер загружаемого файла не является проблемой, и вы готовы решить множество проблем, выберите один из трех указанных выше.
Обновление Q3 2020
Порт JavaScript был интегрирован в MicroPython. Он живет в
портах / javascript .
Порт доступен в виде пакета npm под названием MicroPython.js . Вы можете попробовать это в RunKit .
В Rust есть активно разрабатываемая реализация Python под названием
RustPython . Поскольку Rust официально поддерживает WebAssembly в качестве цели компиляции , неудивительно, что прямо в верхней части файла readme есть демонстрационная ссылка . Хотя еще рано. Их отказ от ответственности следует.
RustPython находится в стадии разработки и не должен использоваться в продакшене или в настройках, допускающих ошибки.
Наша текущая сборка поддерживает только подмножество синтаксиса Python.