19

推測しなければならない場合、答えはClojureであると確信していますが、理由はわかりません。論理的に(私には)ClojureScriptの方が速いはずです:

どちらも「動的」ですが、ClojureScript

  • V8で実行されているJavaScriptにコンパイルします
  • V8エンジンは、間違いなく最速の動的言語エンジンです。
  • V8はCで書かれています

一方、Clojure:

  • ダイナミックでもあります
  • 動的サポートが組み込まれていないJVMで実行されるため、動的サポートを有効にするには、JVMがV8で実行していることをすべて実行する必要があると考えています。
  • JavaはCよりも遅い

では、ClojureはClojureScriptよりもどのように高速でしょうか?JavaScriptが動的で、Clojureが動的であると言うとき、「動的」とは何か違うことを意味しますか?私は何を見ていませんか?

(もちろん、ClojureScript実際に高速である場合、上記の理由は正しいですか?)

Clojureは何にコンパイルされるのでしょうか....少なくとも質問の一部です。JVM部分は単なるインタープリターにはなれないことは知っていますが(そうでなければClojureScriptの方が高速です)、JVMには「動的」なものがないため、Clojureは通常のバイトコードにコンパイルできません。では、ClojureScriptのコンパイル/実行方法とClojureのコンパイル/実行方法とプレーンJavaのコンパイル/実行方法の違いと、それぞれに含まれるパフォーマンスの違いは何ですか?

4

3 に答える 3

32

実際、V8はC++で書かれています。ただし、基本的にはJVMと同じことを行い、JVMはCで記述されています。V8JITはJavascriptコードであり、JITされたコードを実行します。同様に、JVM JITはバイトコード(Javaではなく)をコンパイル(またはホットスポットコンパイル)し、生成されたコードを実行します。

Javaのように、バイトコードは静的ではありません。実際、それは非常に動的である可能性があります。一方、Javaはほとんど静的であり、Javaをバイトコードと混同することは正しくありません。JavaコンパイラはJavaソースコードをバイトコードに変換し、JVMはバイトコードを実行します。詳細については、John Roseのブログ()を参照することをお勧めします。そこにはたくさんの良い情報があります。また、Cliff Clickによる講演を探してみてください(このように)。

同様に、Clojureコードはバイトコードに直接コンパイルされ、JVMはそのバイトコードで同じプロセスを実行します。Clojureのコンパイルは通常、実行時に実行されますが、これは最速のプロセスではありません。同様に、ClojurescriptからJavascriptへの変換も高速ではありません。V8によるJavascriptの実行可能形式への変換は明らかに非常に高速です。Clojureは事前にバイトコードにコンパイルすることができ、それにより多くの起動オーバーヘッドを排除できます。

あなたが言ったように、JVMがバイトコードを解釈すると言うのも実際には正しくありません。1.0リリースは17年以上前にそれを行いました!

従来、2つのコンパイルモードがありました。最初のモードはJIT(Just in Time)コンパイラです。バイトコードがマシンコードに直接変換される場合。JavaのJITコンパイルは高速に実行され、高度に最適化されたコードは生成されません。正常に動作します。

2番目のモードはホットスポットコンパイラと呼ばれます。ホットスポットコンパイラは非常に洗練されています。インタプリタモードでプログラムを非常に迅速に起動し、プログラムの実行時に分析します。ホットスポット(頻繁に実行されるコード内のスポット)を検出すると、それらをコンパイルします。JITコンパイラは、JITされない限り何も実行されないため、高速である必要がありますが、ホットスポットコンパイラは、コンパイルするコードからsnotを最適化するために余分な時間を費やす余裕があります。

さらに、後で戻ってそのコードを再検討し、必要かつ可能であれば、さらに最適化を適用することができます。これは、ホットスポットコンパイラがコンパイルされたC /C++を打ち負かし始めることができるポイントです。コードの実行時の知識があるため、静的C /C++コンパイラでは実行できない最適化を適用する余裕があります。たとえば、仮想関数をインライン化できます。

ホットスポットにはもう1つの機能があります。私の知る限り、他の環境にはない機能ですが、必要に応じてコードを最適化解除することもできます。たとえば、コードが継続的に単一のブランチを取得していて、それが最適化され、実行時の条件が変化して、コードが他の(最適化されていない)ブランチを強制的に停止し、パフォーマンスが突然ひどくなる場合です。ホットスポットは、その機能を最適化解除し、分析を再開して、機能をより適切に実行する方法を見つけることができます。

ホットスポットの欠点は、開始が少し遅いことです。Java 7 JVMの1つの変更は、JITコンパイラとホットスポットコンパイラを組み合わせることです。ただし、このモードは新しく、デフォルトではありませんが、最初の起動が適切であると、JVMが得意とする高度な最適化を開始できます。

乾杯!

于 2012-12-11T03:24:15.693 に答える
27

この質問に正確に答えるのは、特定のベンチマークタスク(または特定のバージョンのClojureまたはClojureScript)を参照しないと困難です。

そうは言っても、ほとんどの場合、Clojureの方がやや速いと思います。理由:

  • Clojureは通常、静的コードにコンパイルされるため、実行時に動的ルックアップを実際に実行することはありません。これは非常に重要です。高性能コードは、静的に型付けされたJavaに非常によく似たバイトコードを生成することがよくあります。問題は、動的言語が実行時に動的メソッドルックアップを実行する必要があるという誤った仮定をしているようです。これは常に当てはまるわけではありません(通常はClojureにはありません)。
  • JVM JITは非常によく設計されており、V8がどれほど優れているとしても、現在でもJavaScriptJITよりも少し優れていると思います。
  • 同時実行性が必要な場合、または複数のコアを利用する必要がある場合は、JavaScriptがシングルスレッドであるため、明らかにコンテストはありません。
  • ClojureコンパイラーはClojureScriptよりも成熟しており、近年、かなり多くのパフォーマンス調整作業が行われています(プリミティブサポート、プロトコルなどを含む)。

もちろん、どの言語でも高速または低速のコードを書くことができます。これにより、言語実装間の基本的な違いよりも大きな違いが生じます。

そしてもっと基本的に、ClojureとClojureScriptのどちらを選択するかは、どのような場合でもパフォーマンスに関するものであってはなりません。どちらも魅力的な生産性の利点を提供します。主な決定要因は次のとおりです。

  • Webで実行する場合は、ClojureScriptを使用してください
  • JVM環境のサーバーで実行する場合は、Clojureを使用します
于 2012-12-11T04:07:31.750 に答える
2

これは歴史的なコメントほどの答えではありません。HotSpotVMとV8jsエンジンはどちらも、SunMicrosystemsのSelfプロジェクトに起源をたどることができます。彼らがするように。それらの両方を比較するときに考慮すべきことがあります。私はこれをコメントとして投稿したでしょうが、評判システムは私を妨げました。

于 2015-03-22T14:31:38.473 に答える