WebAssembly vs asm.js.
Schauen wir uns zunächst an, wie sich WebAssembly im Prinzip von asm.js unterscheidet und ob das Potenzial besteht, vorhandenes Wissen und Tools wiederzuverwenden. Folgendes gibt einen ziemlich guten Überblick:
Fassen wir noch einmal zusammen: WebAssembly (MVP, da ungefähr mehr auf der Roadmap steht):
- ist ein Binärformat von AST mit statischer Typisierung, das von vorhandenen JavaScript-Engines (und damit JIT-fähigen oder kompilierten AOT) ausgeführt werden kann.
- Es ist 10-20% kompakter (komprimierter Vergleich) und um eine Größenordnung schneller zu analysieren als JavaScript.
- Es kann mehr Operationen auf niedriger Ebene ausdrücken, die nicht in die JavaScript-Syntax passen. Lesen Sie asm.js (z. B. 64-Bit-Ganzzahlen, spezielle CPU-Anweisungen, SIMD usw.).
- ist (bis zu einem gewissen Grad) konvertierbar zu / von asm.js.
Daher ist WebAssembly derzeit eine Iteration auf asm.js und zielt nur auf C / C ++ (und ähnliche Sprachen) ab.
Python im Web
Es sieht nicht so aus, als ob GC das einzige ist, was Python-Code davon abhält, auf WebAssembly / asm.js abzuzielen. Beide repräsentieren statisch typisierten Code auf niedriger Ebene, in dem Python-Code nicht (realistisch) dargestellt werden kann. Da die aktuelle Toolchain von WebAssembly / asm.js auf LLVM basiert, kann eine Sprache, die einfach in LLVM IR kompiliert werden kann, in WebAssembly / asm.js konvertiert werden. Aber leider ist Python zu dynamisch, um auch hinein zu passen, wie Unladen Swallow und mehrere Versuche von PyPy beweisen .
Diese Präsentation von asm.js enthält Folien zum Status dynamischer Sprachen . Dies bedeutet, dass derzeit nur die gesamte VM (Sprachimplementierung in C / C ++) in WebAssembly / asm.js kompiliert und (wenn möglich mit JIT) Originalquellen interpretiert werden können. Für Python gibt es mehrere bestehende Projekte:
PyPy: PyPy.js (Autorenvortrag bei PyCon ). Hier ist Release Repo . Die Haupt-JS-Datei pypyjs.vm.js
ist 13 MB (2 MB später gzip -6
) + Python stdlib + anderes Zeug.
CPython: Pyodid , EmPython , CPython-Emscripten , EmCPython usw. empython.js
sind 5,8 MB (2,1 MB danach gzip -6
), keine Standardlib.
Micropython: diese Gabel .
Da dort keine JS-Datei erstellt wurde, konnte ich sie mit trzeci/emscripten/
einer vorgefertigten Emscripten-Toolchain erstellen . Etwas wie:
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
Es produziert micropython.js
1,1 MB (225 KB danach gzip -d
). Letzteres ist bereits zu beachten, wenn Sie nur eine sehr konforme Implementierung ohne stdlib benötigen.
Um einen WebAssembly-Build zu erstellen, können Sie Zeile 13 von Makefile
to ändern
CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Dann make -j
produziert:
113 KB micropython.js
240 KB micropython.wasm
Sie können sich die HTML-Ausgabe von ansehen emcc hello.c -s WASM=1 -o hello.html
, um zu sehen, wie diese Dateien verwendet werden.
Auf diese Weise können Sie möglicherweise auch PyPy und CPython in WebAssembly erstellen, um Ihre Python-Anwendung in einem kompatiblen Browser zu interpretieren.
Eine andere potenziell interessante Sache ist hier Nuitka , ein Python-zu-C ++ - Compiler. Möglicherweise ist es möglich, Ihre Python-App in C ++ zu erstellen und sie dann zusammen mit CPython mit Emscripten zu kompilieren. Aber praktisch habe ich keine Ahnung, wie es geht.
Lösungen
Wenn Sie vorerst eine herkömmliche Website oder Web-App erstellen, bei der das Herunterladen einer JS-Datei mit mehreren Megabyte kaum möglich ist, sollten Sie sich Python-zu-JavaScript-Transpiler (z. B. Transcrypt ) oder JavaScript-Python-Implementierungen (z. B. Brython ) ansehen ). Oder versuchen Sie Ihr Glück mit anderen aus der Liste der Sprachen, die zu JavaScript kompiliert werden .
Andernfalls können Sie zwischen den drei oben genannten Optionen wählen, wenn die Downloadgröße kein Problem darstellt und Sie bereit sind, viele Ecken und Kanten zu beseitigen.
Q3 2020 Update
Der JavaScript-Port wurde in MicroPython integriert . Es lebt in
Ports / Javascript .
Der Port ist als npm-Paket mit dem Namen MicroPython.js verfügbar . Sie können es in RunKit ausprobieren .
In Rust gibt es eine aktiv entwickelte Python-Implementierung namens
RustPython . Da Rust WebAssembly offiziell als Kompilierungsziel unterstützt , ist es keine Überraschung, dass sich der Demo-Link ganz oben in der Readme-Datei befindet. Es ist jedoch früh. Ihr Haftungsausschluss folgt.
RustPython befindet sich in einer Entwicklungsphase und sollte nicht in der Produktion oder in einer Umgebung mit Fehlertoleranz verwendet werden.
Unser aktueller Build unterstützt nur eine Teilmenge der Python-Syntax.