[解決済み] PythonからWebAssemblyへのコンパイル
質問
Python 2.7のコードをWeb Assemblyに変換することが可能であることを読みましたが、その方法に関する決定的なガイドを見つけることができません。
今のところ、私は Emscripten とその必要なすべてのコンポーネントを使用して C プログラムを Web Assembly にコンパイルしたので、それが動作していることは分かっています (使用したガイド。 http://webassembly.org/getting-started/developers-guide/ )
Ubuntu マシンでこれを行うには、どのような手順を踏まなければなりませんか?PythonコードをLLVMビットコードに変換し、Emscriptenを使用してそれをコンパイルしなければなりませんか?もしそうなら、どのように私はこれを達成するのでしょうか?
どのように解決するのですか?
WebAssemblyとasm.jsの比較
まず、原理的にどうなのかを見てみましょう。 WebAssembly とはどのように違うのかを見てみましょう。 asm.js とは異なるのか、そして既存の知識やツールを再利用できる可能性があるのか、などです。以下は、かなり良い概要を示しています。
おさらいですが、WebAssembly(MVP、詳しくは そのロードマップ , ざっくりと)。
- は、既存のJavaScriptエンジンで実行可能な、静的型付けによるASTのバイナリ形式です(したがって、JIT-ableまたはコンパイルされたAOT)。
- は、JavaScript よりも 10-20% コンパクトで (gzip で圧縮した比較)、パースも桁違いに高速です。
- JavaScript の文法に当てはまらないような低レベルの操作をより多く表現でき、asm.js を読むことができます (例: 64 ビット整数、特殊な CPU 命令、SIMD など)。
- は、asm.js との間で (ある程度) 変換可能です。
このように、現在WebAssemblyはasm.jsの反復であり、C/C++(および類似の言語)だけを対象としています。
Web 上の Python
PythonのコードがWebAssembly/asm.jsをターゲットにするのを止めるのはGCだけではなさそうです。どちらも低レベルの静的型付けされたコードであり、Pythonコードは(現実的には)表現することができないのです。WebAssembly/asm.jsの現在のツールチェーンはLLVMに基づいているので、LLVM IRに簡単にコンパイルできる言語は、WebAssembly/asm.jsに変換することができます。しかし、残念なことに、Pythonはあまりにも動的で、それに適合することはできません。 アンラッドスワロー と いくつかの試み のPyPyの。
このasm.jsのプレゼンテーションには 動的言語の現状についてのスライド . これが意味するところは、現在のところ、VM(C/C++による言語実装)全体をWebAssembly/asm.jsにコンパイルし、オリジナルのソースを(可能な限りJITで)解釈することしかできない、ということです。Pythonについては、いくつかの既存のプロジェクトがあります。
-
PyPyです。 PyPy.js (作者の PyCon での講演 ). ここでは リリースレポ . メインのJSファイルです。
pypyjs.vm.js
は 13 MB です(2MB 後gzip -6
) + Python stdlib + その他のものです。 -
CPythonです。 パイオダイド , EmPython , CPython-Emscripten , EmCPython など
empython.js
は5.8MB(2.1MB後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 # to run REPL: npm install && nodejs server.js
これは
micropython.js
は 1.1 MB (225 KB) になります。gzip -d
). 後者は、stdlibなしの非常に準拠した実装だけが必要な場合、すでに考慮すべき点です。WebAssemblyのビルドを行うには、以下のように
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
のHTML出力を見ると、これらのファイルをどのように使うかがわかります。この方法で、WebAssemblyでPyPyとCPythonをビルドして、準拠したブラウザでPythonアプリケーションを解釈することもできる可能性があります。
ここでもう一つ潜在的に興味深いのは ヌイグルミ という、Python から C++ へのコンパイラです。潜在的には、PythonアプリケーションをC++にビルドして、EmscriptenでCPythonと一緒にコンパイルすることが可能かもしれません。しかし、現実的にはどうすればいいのかわかりません。
ソリューション
当面の間、数メガバイトのJSファイルをダウンロードするのが難しいような従来のWebサイトやWebアプリを構築している場合は、PythonからJavaScriptへのトランスパイラ(例. トランスクリプト など)やJavaScriptのPython実装(例: ブライソン ). あるいは JavaScript にコンパイル可能な言語のリスト .
その他、ダウンロードサイズが問題ではなく、多くの荒削りな部分に取り組む準備ができているのであれば、上記の3つから選んでください。
2020年第3四半期アップデート
-
JavaScriptポート は統合されました を MicroPython に統合しました。これは ポート/javascript .
-
というnpmパッケージで提供されています。 MicroPython.js . で試すことができます。 RunKit .
-
Rustで活発に開発されているPythonの実装で、次のようなものがあります。 RustPython . Rust は公式に としてWebAssemblyをサポートしているからです。 コンパイルターゲット があっても不思議ではありません。 デモリンク があるのは当然です。 があるのも当然です。とはいえ、早い話。彼らの免責事項は以下の通りです。
RustPythonは開発段階であり、実稼働環境または耐障害性の高い環境で使用するべきではありません。 生産現場やフォールトイントレラントな環境では使用しないでください。
現在のビルドでは、Pythonの構文のサブセットのみをサポートしています。
関連
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonで辞書に新しいキーを追加するにはどうすればよいですか?
-
[解決済み] Pythonで2つのリストを連結する方法は?
-
[解決済み] Pythonでファイルやフォルダを削除する方法は?
-
[解決済み] Pythonで例外を手動で発生(スロー)させる
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] PythonからSMTPを使用してメールを送信する
-
[解決済み] Django 1.7で初期マイグレーションからマイグレートバックする方法は?
-
[解決済み] Python Logging でログメッセージが2回表示される件
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 2つの線分が交差しているかどうかを確認するにはどうすればよいですか?
-
[解決済み] Pythonの構文に新しいステートメントを追加することはできますか?
-
[解決済み] googletransがエラー 'NoneType' オブジェクトに 'group' 属性がない、と言って動かなくなった。
-
[解決済み] SQLAlchemy: 日付フィールドをフィルタリングする方法は?
-
[解決済み] データフレームをソートした後にインデックスを更新する
-
[解決済み] Jupyter (IPython)ノートブックのセッションをpickleして保存する方法
-
[解決済み] 異なる順序で同じ要素を持つ2つのJSONオブジェクトを等しく比較するには?
-
[解決済み] Pandasのデータフレーム内の文字列を'date'データ型に変換するにはどうしたらいいですか?
-
[解決済み] 単純な文字列からtimedeltaオブジェクトを作成する方法
-
[解決済み] 認証プラグイン 'caching_sha2_password' はサポートされていません。