質問を読みました asm.jsでテストおよび開発する方法 、受け入れられた回答は http://kripken.github.com/mloc_emscripten_talk/#/ へのリンクを提供します。
このスライドショーの結論は、「統計的に型付けされた言語、特にC/C++はJavaScriptに効果的にコンパイルできるため、「コンパイルされたC/C++の速度を期待して、今年後半にネイティブコードよりも2倍遅くなるか、より良い速度になります "。
しかし、通常のJavaScript自体など、静的に型付けされていない言語はどうでしょうか。 asm.jsにコンパイルできますか?
JavaScript自体をasm.jsにコンパイルできますか?
そうではありません。その動的な性質のためです。コンパイルしようとするときと同じ問題です Cへ または ネイティブコードへ -実際にVM少なくとも、そのようなVMは可能です:
js.js は、JavaScriptのJavaScriptインタープリターです。インタプリタをゼロから作成しようとする代わりに、 SpiderMonkey が [〜#〜] llvm [〜#〜] にコンパイルされ、次に emscripten が変換されますJavaScriptへの出力。
しかし、asmjsコードが通常のJSよりも高速に実行される場合、JSをasmjsにコンパイルするのは理にかなっていますか?
いいえ。 asm.js は非常に制限されたJSのサブセットであり、簡単にバイトコードに変換できます。ただし、この利点を得るには、まずJSのすべての高度な機能をそのサブセットに分解する必要があります。これは非常に複雑なタスクです。しかし、JavaScriptエンジンは、これらのすべての高度な機能を直接バイトコードに変換するように設計および最適化されています-なぜasm.jsのような中間ステップに悩まされるのですか? Js.jsは、「ネイティブ」JSの約200倍遅いと主張しています。
そして、一般的に静的に型付けされていない言語はどうですか?
スライドショーでは ... Just C/C++? 以降から説明しています。具体的には:
C/C++ランタイム全体をコンパイルし、元の言語を適切なセマンティクスで解釈できますが、これは軽量ではありません
このような言語からJavaScriptへのソースからソースへのコンパイラは、セマンティックの違い(たとえば、数値型)を無視します
実際、これらの言語は効率的にするために特別なVMに依存しています
それらのソースからソースへのコンパイラは、それらのVMで行われた最適化を失います。
「それは可能ですか?」という一般的な質問に答えてその答えは、JavaScriptとasm.jsサブセットの両方がチューリング完全であるため、翻訳が存在するということです。
これを実行してパフォーマンスの向上を期待するかどうかは、別の質問です。短い答えは「いいえ、あなたはすべきではありません」です。これは、圧縮ファイルを圧縮しようとすることに例えられます。はい、圧縮アルゴリズムを実行することは可能ですが、一般に、結果のファイルが小さくなると期待すべきではありません。
簡単な答え:動的に型付けされた言語のパフォーマンスコストは、コードの意味に由来します。同等の意味を持つ静的に型付けされたプログラムは、同じコストを負担します。
これを理解するためには、whyasm.jsがパフォーマンス上の利点を提供することを理解することが重要です。または、より一般的には、静的に型付けされた言語が動的に型付けされた言語よりもパフォーマンスが優れている理由。短い答えは「ランタイム型チェックには時間がかかります」であり、長い答えには、静的に型付けされたコードを最適化する改善された実行可能性が含まれます。例えば:
function a(x) { return x + 1; }
function b(x) { return x - 1; }
function c(x, y) { return a(x) + b(y); }
x
とy
が両方とも整数であることがわかっている場合、関数c
をいくつかのマシンコード命令に最適化できます。それらが整数または文字列である可能性がある場合、最適化の問題ははるかに困難になります。場合によってはこれらを文字列の追加として扱い、その他の場合は追加として扱う必要があります。特に、c
で発生する加算演算には4つの可能な解釈があります。それは、追加、文字列の追加、または強制的に文字列と追加の2つの異なるバリアントである可能性があります。可能なタイプをさらに追加すると、可能な順列の数が増えます。動的に型付けされた言語の最悪の場合、k ^ nnを含む式の可能な解釈があります。 それぞれが任意の数のkタイプを持つことができる用語。静的に型付けされた言語では、k = 1であるため、特定の式の解釈は常に1つです。このため、オプティマイザーは、動的に型付けされたコードよりも静的に型付けされたコードの最適化において根本的に効率的です。最適化の機会を検索する際に考慮する順列が少なくなります。
ここでのポイントは、動的に型付けされたコードから静的に型付けされたコードに変換するとき(JavaScriptからasm.jsに移行するときのように)、元のコードのセマンティクスを考慮する必要があるということです。タイプチェックの意味はまだあり(静的に型付けされたコードで記述されています)、コンパイラを抑圧するためにそれらのすべての順列がまだ存在しています。
asm.jsについてのいくつかの事実。
はい、asm.js方言を手書きで書くことができます。
asm.jsの例をご覧になった場合、それらはユーザーフレンドリー。明らかに、Javascriptはこのコードを作成するためのフロントエンド言語ではありません。
Vanilla Javascriptをasm.js方言に翻訳することはnotできません。
考えてみてください-すでに標準のJavascriptを完全に静的に変換できるのであれば、なぜasm.jsが必要なのでしょうか? asm.jsの唯一の存在は、一部の人々のJavascript JITの人々は、Javascriptが開発者の努力なしに高速になるという約束をあきらめたことを意味します。
これにはいくつかの理由がありますが、JITが静的コンパイラと同等の動的言語を理解するのは本当に難しいとだけ言っておきましょう。そして、おそらく開発者がJITを完全に理解するために。
最終的には、タスクに適切なツールを使用することに要約されます。静的でパフォーマンスの高いコードが必要な場合は、[〜#〜] c [〜#〜]/C++を使用します(/Java)-動的言語が必要な場合は、Javascriptを使用します、Python、...
asm.jsは、簡単に最適化できるJavaScriptの小さなサブセットが必要なために作成されました。 javascriptをjavascript/asm.jsに変換する方法があれば、asm.jsはもう必要ありません-そのメソッドはjsインタープリターに直接挿入できます。
理論上、asm.jsに存在する言語の限られたサブセットで表現できる場合、JavaScript操作をasm.jsに変換/コンパイル/トランスパイルすることが可能です。ただし、実際には、現時点では通常のJavaScriptをasm.jsに変換できるツールはありません(2017年6月)。
いずれにせよ、静的型付けはasm.jsの要件であり、その欠如が通常のJavaScriptの機能の1つであるため、言語を 静的型付け を使用してasm.jsに変換する方が理にかなっていますasm.jsにコンパイルするのは非常に困難です。
2013年、asm.jsがホットだったときに、 JavaScriptに似た静的に型付けされた言語をコンパイルする が試みられましたが、言語とコンパイラの両方が放棄されたようです。
今日、2017年には、JavaSciptサブセット TypeScript および Flow がasm.jsへの変換に適した候補になりますが、どちらの言語のコア開発チームもそのような変換に関心がありません。 [〜#〜] lljs [〜#〜] にはasm.jsにコンパイルできるフォークがありましたが、そのプロジェクトはほとんど死んでいます。 ThinScript はずっと最近の試みで、TypeScriptに基づいていますが、アクティブでもないようです。
したがって、asm.jsコードを生成する最良かつ最も簡単な方法は、コードをC/C++で記述し、変換/コンパイル/トランスパイルすることです。ただし、近い将来にこれを行うかどうかはまだ不明です。 Web Assembly はすぐにasm.jsを完全に置き換える可能性があり、Web Assemblyに変換する TurboScript や AssemblyScript などのTypeScriptに似た言語が既にポップアップ表示されています。実際、TurboScriptは元々ThinScriptに基づいており、asm.jsにコンパイルするために使用されていましたが、この機能を放棄したようです。
通常のJavaScriptをams.jsに変換するには、最初に Cにコンパイル または C++ を使用し、次に を使用して生成コードをasm.jsにコンパイルします。 Emscripten 。これが実用的かどうかはわかりませんが、それでも興味深いコンセプトです。
最近、JavaScriptをWebAssemblyとASM.jsにコンパイルする NectarJS という別のツールを見つけました。
これを確認してください http://badassjs.com/post/43420901994/asm-js-a-low-level-highly-optimizable-subset-of
基本的に、コードがasm.jsと互換性があることを確認する必要があります(強制や型キャストなし、メモリの管理などが必要です)。この背後にあるアイデアは、javascriptでコードを記述し、ボトルネックを検出し、jimおよび動的コンパイルの代わりにasm.jsおよびaotコンパイルを使用するためにコードの変更を行うことです...少しPITAですが、javascriptまたはその他を使用することができますC++以上のような言語。近い将来、lljs .....