WebAssembly vs asm.js
Najpierw rzućmy okiem jak w zasadzie WebAssembly różni się od asm.js i czy istnieje potencjał do ponownego wykorzystania istniejącej wiedzy i oprzyrządowania. Poniższe daje całkiem dobry przegląd:
Podsumujmy, WebAssembly (MVP, ponieważ w przybliżeniu jest więcej na jego mapie drogowej ):
- jest binarnym formatem AST z typowaniem statycznym, który może być wykonywany przez istniejące silniki JavaScript (a tym samym AOT zdolny do JIT lub skompilowany),
- jest o 10-20% bardziej zwarty (porównanie gzipem) i o rząd wielkości szybszy do przeanalizowania niż JavaScript,
- może wyrazić więcej operacji niskopoziomowych, które nie pasują do składni JavaScript, przeczytaj asm.js (np. 64-bitowe liczby całkowite, specjalne instrukcje procesora, SIMD itp.)
- można zamienić (do pewnego stopnia) na asm.js.
Dlatego obecnie WebAssembly jest iteracją w asm.js i jest przeznaczona tylko dla C / C ++ (i podobnych języków).
Python w sieci
Nie wygląda na to, że GC jest jedyną rzeczą, która powstrzymuje kod Pythona przed celowaniem w WebAssembly / asm.js. Oba reprezentują statycznie typowany kod niskiego poziomu, w którym kod Pythona nie może być (realistycznie) reprezentowany. Ponieważ obecny łańcuch narzędzi WebAssembly / asm.js jest oparty na LLVM, języku, który można łatwo skompilować do LLVM IR, można przekonwertować na WebAssembly / asm.js. Niestety, Python jest zbyt dynamiczny, aby również do niego pasować, o czym świadczy Unladen Swallow i kilka prób PyPy.
Ta prezentacja asm.js zawiera slajdy dotyczące stanu języków dynamicznych . Oznacza to, że obecnie możliwe jest tylko skompilowanie całej maszyny wirtualnej (implementacja języka w C / C ++) do WebAssembly / asm.js i zinterpretowanie (z JIT, jeśli to możliwe) oryginalnych źródeł. W przypadku Pythona istnieje kilka istniejących projektów:
PyPy: PyPy.js ( wykład autora na PyCon ). Oto repozytorium wersji . Główny plik JS pypyjs.vm.js
ma 13 MB (po 2 MB gzip -6
) + stdlib w Pythonie + inne rzeczy.
CPython: pyodide , EmPython , CPython-Emscripten , EmCPython itp. empython.js
To 5,8 MB (po 2,1 MB gzip -6
), brak standardowego biblioteki.
Micropython: ten widelec .
Nie było tam zbudowanego pliku JS, więc mogłem go zbudować za trzeci/emscripten/
pomocą gotowego łańcucha narzędzi Emscripten. Coś jak:
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
Daje micropython.js
1,1 MB (po 225 KB gzip -d
). To ostatnie jest już czymś do rozważenia, jeśli potrzebujesz tylko bardzo zgodnej implementacji bez stdlib.
Aby utworzyć kompilację WebAssembly, możesz zmienić wiersz 13 Makefile
na
CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
Następnie make -j
produkuje:
113 KB micropython.js
240 KB micropython.wasm
Możesz spojrzeć na wynik HTML programu emcc hello.c -s WASM=1 -o hello.html
, aby zobaczyć, jak używać tych plików.
W ten sposób możesz również potencjalnie zbudować PyPy i CPython w WebAssembly, aby zinterpretować aplikację Python w zgodnej przeglądarce.
Inną potencjalnie interesującą rzeczą jest Nuitka , kompilator Pythona do C ++. Potencjalnie możliwe jest zbudowanie aplikacji w języku Python w języku C ++, a następnie skompilowanie jej wraz z CPythonem za pomocą Emscripten. Ale praktycznie nie mam pojęcia, jak to zrobić.
Rozwiązania
Na razie, jeśli tworzysz konwencjonalną witrynę internetową lub aplikację internetową, w której pobranie kilku-megabajtowego pliku JS jest ledwie opcją, spójrz na transpilery Python-to-JavaScript (np. Transcrypt ) lub implementacje JavaScript Python (np. Brython ). Lub spróbuj szczęścia z innymi z listy języków, które kompilują się do JavaScript .
W przeciwnym razie, jeśli rozmiar pobierania nie stanowi problemu i jesteś gotowy, aby poradzić sobie z wieloma nierównymi krawędziami, wybierz jedną z trzech powyższych.
Aktualizacja Q3 2020
Port JavaScript został zintegrowany z MicroPythonem. Żyje w
portach / javascript .
Port jest dostępny jako pakiet npm o nazwie MicroPython.js . Możesz to wypróbować w RunKit .
W Rust istnieje aktywnie rozwijana implementacja języka Python o nazwie
RustPython . Ponieważ Rust oficjalnie obsługuje WebAssembly jako cel kompilacji , nic dziwnego, że na początku pliku readme znajduje się link do wersji demonstracyjnej . Chociaż jest wcześnie. Ich zrzeczenie się następuje.
RustPython jest w fazie rozwoju i nie powinien być używany w środowisku produkcyjnym lub w ustawieniach nietolerujących błędów.
Nasza obecna kompilacja obsługuje tylko podzbiór składni Pythona.