14

Javaは遅いです。

それは「都市伝説」ではなく、事実のようです。レイテンシーのためにライブコーディングには使用せず、クラスター/並列コンピューティングには使用しません。特に「Java vs C# vs C++」など、何千ものベンチマークがあります。

http://benchmarksgame.alioth.debian.org/

上記のサイトによると、Java のパフォーマンスは C とほぼ同じ (他とはかけ離れている) だけでなく、Scala と Clojure (どちらも JVM 上で実行される関数型言語) も OCaml や Erlang よりもパフォーマンスが優れています。

また、「Java は X よりも速い」という意見も多数あります (たとえば、SO に関する質問: Java ランタイム パフォーマンスとネイティブ C / C++ コード? )。

そのため、特定のケースでは Java が高速に見えます。誰かが理由を説明できますか?

動的コード (Scala、Clojure) とガベージ コレクションを指定すると、場合によってはバイトコードがネイティブ コードよりも高速に実行される可能性があるのはなぜですか? より高速であるのに、なぜまだ遅延があるのでしょうか?

ここは矛盾しているようですが、誰かが光を当てることができますか?

4

5 に答える 5

11

プログラミングの首謀者の本の中で、James Gosling は次のように説明しています。

ジェームズ: その通りです。最近では、本当に優れた C および C++ コンパイラをほぼ常に打ち負かしています。動的コンパイラを使用すると、最後の瞬間にコンパイラが正しく実行されている場合に 2 つの利点が得られます。1 つは、実行しているチップセットを正確に把握していることです。多くの場合、人々が C コードの一部をコンパイルするとき、ある種の一般的な x86 アーキテクチャで実行するためにコンパイルする必要があります。入手したバイナリの中で、特によく調整されているものはほとんどありません。Mozilla の最新コピーをダウンロードすると、ほぼすべての Intel アーキテクチャ CPU で動作します。Linux バイナリはほぼ 1 つです。これは非常に汎用的で、あまり優れた C コンパイラではない GCC でコンパイルされています。

HotSpot が実行されると、実行中のチップセットが正確に認識されます。キャッシュがどのように機能するかを正確に知っています。メモリ階層がどのように機能するかを正確に認識しています。すべてのパイプライン インターロックが CPU でどのように機能するかを正確に認識しています。このチップが持っている命令セットの拡張機能を認識しています。使用しているマシンを正確に最適化します。残りの半分は、実行中のアプリケーションを実際に見ることです。何が重要かを知る統計を持つことができます。C コンパイラでは不可能なことをインライン化できます。Java の世界でインライン化される種類のものは、非常に驚​​くべきものです。次に、ストレージ管理が最新のガベージ コレクターと連携する方法に取り組みます。最新のガベージ コレクターを使用すると、ストレージの割り当てが非常に高速になります。

于 2011-04-12T21:09:28.233 に答える
9

高速 JVM は Just-In-Time (JIT) コンパイルを使用します。バイトコードは、実行時にオンザフライでネイティブ コードに変換されます。JIT は、最適化のための多くの機会を提供します。JIT の詳細については、このウィキペディアの記事を参照してください。

于 2011-04-12T20:44:43.570 に答える
4

JVM にはさまざまな種類があります。

最速のものは、収集されるパフォーマンス特性に基づいて、バイト コードをオンザフライでネイティブ コードにコンパイルします。これらはすべて追加のメモリを必要とするため、メモリを犠牲にして速度を購入します。また、最高速度に達するまでに時間がかかるため、短期間のプログラムではメリットがありません。

それでも、JamVMインタープリター (Oracle JVM に比べて小さい) は、コンパイルされた JVM の妥当な部分の最高速度に達します。

ガベージ コレクションに関しても、十分なメモリを利用できることが速度の向上につながります。また、真のメリットは、オブジェクトが使用されなくなった時点を追跡する責任をコードから取り除くことです。これにより、プログラムが単純になり、エラーが発生しにくくなります。

于 2011-04-12T20:44:49.623 に答える
3

まあ、これは古い議論です。ほとんどすべてが Emacs および VI として普及しています (ただし、それほど古いものではないことは間違いありません)。多くの C++ 開発者が、ほとんどのパフォーマンス ベンチマーク (特に Java が c++__ と同じくらい高速であることに言及) が歪んでいる理由について多くの議論を提供しているのを見てきましたが、正直なところ、彼らには一理あります。

Java が C++ と同じくらい高速である理由を詳しく説明するのに十分な知識や時間はありませんが、次の理由が考えられます...

1- 2 人の非常に有能な開発者に、現実世界の問題 (同じ問題) に対して Java と C++ でコードを書くように依頼すると、Java が C++ よりも高速に実行されることに驚かれることでしょう。C++ は、適切に作成された場合、Java が使用するメモリの一部を使用します。(Java オブジェクトは少し肥大化しています)。

2- Java は本質的により単純な言語であることを意図しており、次善のコードを書くのが難しいことを確認するために書かれています。メモリ管理を抽象化し、低レベルの最適化を処理することにより、Java では C++ よりも優れたコードを簡単に記述できます。(これが最も重要なことだと思います.... Javaで悪いコードを書くのは難しいです)。反対に、優れたC++開発者は、Javaの自動GCよりもはるかに優れたメモリ管理を処理できます。(Javaはすべてをヒープに保存するため、より多くのメモリを使用します...)

3- Java コンパイラは一貫して改善されており、ホットスポットのようなアイデアはマーケティング用語よりも優れていることが証明されています。(JIT が導入されたとき、それは単なるマーケティング用語でした.. 私によると.. :))

4-人間工学に基づいて、または基礎となるオペレーティングシステムのパラメーターに基づいて設定を調整すると、Java ハンドルのバリエーションが改善されます。そのため、一部の環境では、Java が C++ と同等のパフォーマンスを発揮することをイメージするのは難しくありません。

5- Java 開発者向けに高レベルの並行性と並列性 API を開放することも理由の 1 つです。Java 同時実行パッケージは、今日のマルチ プロセッサ環境を活用できる高性能コードを作成するための最も簡単な方法であることはほぼ間違いありません。

6- ハードウェアがますます安価になるにつれて、開発者の能力がより大きな要因になってきました。そのため、世の中に出回っている多くの C++ コードはおそらく Java よりも遅いと思います。

于 2011-04-12T21:04:11.230 に答える
2

Java Byte コードは、ほとんどのネイティブ オペコードよりも最適化がはるかに簡単です。バイトコードが制限されているため、危険なことを行うことができないため、より完全に最適化できます。たとえば、ポインターのエイリアシングを考えてみましょう。http://en.wikipedia.org/wiki/Pointer_aliasing

C/c++ でできること

char[] somebuffer = getABuffer();
char* ptr = &someBuffer[2];
memcpy(ptr, somebuffer, length);

これにより、何が何を参照しているのかわからないため、場合によっては最適化が難しくなります。Java では、この種のことは許可されていません。

一般に、より高いレベルの抽象化で実行できるコードの変更は、オブジェクト コードで実行できるものよりもはるかに強力です。

于 2011-04-12T20:54:15.527 に答える