WebAssembly проти asm.js
По-перше, давайте подивимося, чим, в принципі, WebAssembly відрізняється від asm.js , і чи існує потенціал для повторного використання наявних знань та інструментів. Далі подано досить хороший огляд:
Давайте рекапітулюємо WebAssembly (MVP, оскільки в дорожній карті приблизно є більше):
- - це двійковий формат AST зі статичним набором тексту, який може виконуватися існуючими механізмами JavaScript (і, отже, з підтримкою JIT або компільованим AOT),
- він на 10-20% компактніший (gzipped порівняння) і на порядок швидше аналізується, ніж JavaScript,
- він може виражати більш низькорівневі операції, які не вписуються в синтаксис JavaScript, читати asm.js (наприклад, 64-розрядні цілі числа, спеціальні інструкції процесора, SIMD тощо)
- конвертована (певною мірою) в / з asm.js.
Таким чином, на даний момент WebAssembly є ітерацією на asm.js і націлена лише на C / C ++ (та подібні мови).
Python в Інтернеті
Схоже, GC - це єдине, що перешкоджає коду 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
, становить 13 МБ (2 МБ після gzip -6
) + Python stdlib + інші матеріали.
CPython: піодид , 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
Він виробляє 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-to-JavaScript (наприклад, Transcrypt ) або реалізації JavaScript Python (наприклад, Brython ). Або спробуйте свою удачу з іншими зі списку мов, які компілюються на JavaScript .
В іншому випадку, якщо розмір завантаження не є проблемою, і ви готові вирішити багато нерівних країв, виберіть один із трьох варіантів.
Оновлення Q3 2020
Порт JavaScript був інтегрований в MicroPython. Він живе в
портах / javascript .
Порт доступний як пакет npm під назвою MicroPython.js . Ви можете спробувати це в RunKit .
У Rust активно розробляється реалізація Python, яка називається
RustPython . Оскільки Rust офіційно підтримує WebAssembly як ціль компіляції , не дивно, що демонстраційне посилання знаходиться у верхній частині readme. Хоча рано. Далі йдеться про їх застереження.
RustPython перебуває на стадії розробки, і його не слід використовувати у виробництві або в умовах непереносимості несправностей.
Наша поточна збірка підтримує лише підмножину синтаксису Python.