Javaは本当に遅いのですか?


180

Javaは遅いことである程度の評判があります

  • Javaは本当に遅いのですか?
  • はいの場合、なぜですか?ボトルネックはどこにありましたか(またはありましたか)?非効率なJVMが原因ですか?ガベージコレクション?JNIでラップされたCコードの代わりに純粋なバイトコードライブラリ?他の多くの言語にはこれらの機能がありますが、速度が遅いという評判はありません。

35
人々はとても緊張します...これがどのように主観的であることができるか、それが議論の余地があるかを見ないでください。「なぜバブルソートが遅いのか」などでも同じ結果になるのでしょうか。私は技術的な質問をし、技術的な回答(私が得た)を望みましたが、主観的で議論の余地があるように質問を閉じるのはばかげています。
Stefano Borini、2010年

1
私はトップコメントのほとんどを読みましたが、C#GUIベースのデスクトップアプリケーションは、最新のものを含め、どのJava GUIベースのデスクトップアプリケーションよりもはるかに高速に実行されるという明白な事実に対応しているようには見えません。
BobTurbo 2011

3
.net webforms、.net MVC、PHP、Rails、Django、およびJavaでのSpring(私は聞いたことが良いと思います)以外のさまざまなものすべてを扱ってきたクライアント側のWeb開発者として、パフォーマンス/アーキテクチャが低いことを期待していますJavaチームによって構築されたバックエンドから。私は本当の問題はベンチマークではなく、むしろ平凡なJava開発者のがらくたがあるという問題を疑っています。それは言語のせいではありません。実際に自分の技術を磨き、Java以外の言語を学ぶのは、Java開発者のせいではありません。ただし、Sun、認定、90年代、およびIT業界全般のせいかもしれません。
エリック・レッペン、2012

回答:


236

現代のJavaは、記憶を独占しているにもかかわらず、最速の言語の1つです。Java 、VMの起動に長い時間がかかっていたため、遅いという評判がありました。

それでもJavaが遅いと思われる場合、ベンチマークゲームの結果をご覧ください。事前にコンパイルされた言語(C、Fortranなど)で書かれた厳密に最適化されたコードは、それを打ち負かすことができます。ただし、JavaはPHP、Ruby、Pythonなどの10倍以上の速さです。一般的なコンパイル言語(標準ライブラリを使用している場合)に勝る特定の領域があります。

現在、「遅い」Javaアプリケーションの言い訳はありません。言語よりもはるかに、開発者とレガシーコード/ライブラリが原因です。また、何でも「企業」のせいにします。

「Javaは遅い」という観客に公平を期して、これはまだ遅い領域です(2013年に更新)。

  • ライブラリは多くの場合、パフォーマンスではなく「正確さ」と読みやすさを目的として作成されています。私の意見では、これがJavaの評判、特にサーバー側の評判が依然として悪い主な理由です。これは文字列の問題を指数関数的に悪化させます。いくつかの単純な間違いがよくあります。オブジェクトは多くの場合、プリミティブの代わりに使用され、パフォーマンスを低下させ、メモリ使用量を増やします。多くのJavaライブラリ(標準ライブラリを含む)は、可変またはより単純な形式(char []またはStringBuffer)を再利用するのではなく、文字列を頻繁に作成します。これは遅く、後で収集する大量のゴミを作成します。これを修正するために、開発者は可能な限りプリミティブコレクション、特にJavalutionのライブラリを使用することをお勧めします。

  • 文字列操作は少し遅いです。Javaは不変のUTF-16でエンコードされた文字列オブジェクトを使用します。つまり、より多くのメモリとより多くのメモリアクセスが必要になり、一部の操作はASCII(C、C ++)よりも複雑になります。当時、これは移植性の正しい決定でしたが、パフォーマンスコストはわずかです。UTF-8は今より良い選択のように見えます。

  • 境界チェックのため、配列アクセスはCに比べて少し遅くなります。以前は大きなペナルティでしたが、現在は小さくなっています(Java 7は冗長な境界チェックの多くを最適化します)。

  • 任意のメモリアクセスがないと、一部のI / Oとビットレベルの処理が遅くなる可能性があります(圧縮/解凍など)。これは現在、ほとんどの高級言語の安全機能です。

  • JavaはCよりも多くのメモリを使用します。アプリケーションがメモリ制限またはメモリ帯域幅制限(キャッシュなど)の場合、これにより処理速度が低下します。逆に、割り当て/割り当て解除は非常に高速です(高度に最適化されています)。これは現在、ほとんどの高水準言語の機能であり、オブジェクトと明示的なメモリ割り当てではなくGCの使用によるものです。 加えて、悪いライブラリの決定。

  • ストリームベースのI / Oは、ストリームアクセスごとに同期を必要とする(IMO、不適切な選択)ために低速です。NIOはこれを修正しましたが、使用するのは面倒です。一度に要素ではなく配列に対して読み取り/書き込みを行うことで、これを回避できます。

  • JavaはCが提供するのと同じ低レベルの機能を提供しないため、一部の操作を高速化するためにダーティインラインアセンブラトリックを使用することはできません。これは移植性を提供し、現在ほとんどの高級言語の機能です。

  • Javaアプリケーションが非常に古いバージョンのJVMに関連付けられていることはよくあります。特にサーバー側。これらの古いJVMは、最新バージョンと比較して信じられないほど非効率的です。

結局のところ、Javaは、ある程度のパフォーマンスを犠牲にしてセキュリティと移植性を提供するように設計されており、Javaが示す非常に要求の厳しい操作のために設計されています。遅いという評判のほとんどは、もはや当然のことではありません。


ただし、Javaが他のほとんどの言語より高速である場所がいくつかあります。

  • メモリの割り当てと割り当て解除は高速で安価です。キャッシュされたものを再利用するよりも、新しいマルチkBアレイを割り当てる方が20%高速(またはそれ以上!)であるケースを見てきました。

  • オブジェクトのインスタンス化とオブジェクト指向の機能は、最初から設計されているため、非常に高速に使用できます(場合によってはC ++より高速)。これは、明示的な割り当てではなく、適切なGCによるものです(多くの小さなオブジェクトの割り当てにより適しています)。これを克服するCをコーディングできます(カスタムメモリ管理をローリングし、mallocを効率的に実行することにより)。しかし、それは簡単ではありません。

  • メソッド呼び出しは基本的に無料で、場合によっては大きなメソッドのコードより高速です。HotSpotコンパイラが最適化メソッド呼び出しに実行情報を使用し、非常に効率的なインライン化があります。追加の実行情報を使用することにより、事前のコンパイラーや(まれに)手動のインライン化よりもパフォーマンスが向上する場合があります。C / C ++と比較してください。コンパイラーがインライン化しないことを決定した場合、メソッド呼び出しには小さなパフォーマンス上のペナルティが伴います。

  • 同期とマルチスレッドは簡単で効率的です。Javaは最初からスレッド対応になるように設計されており、それが示しています。最近のコンピューターは通常、複数のコアを備えており、スレッド化は言語に組み込まれているため、非常に簡単に利用できます。基本的に、標準のシングルスレッドCコードと比較して、速度が100%から300%向上します。はい、注意深く書かれたCのスレッドとライブラリはこれに勝るものですが、それはプログラマにとって多くの追加作業です。

  • 文字列には長さが含まれます。一部の操作はより高速です。これは、ヌルで区切られた文字列(Cで一般的)を使用するよりも優れています。Java 7では、人々が愚かにそれを使用していて、メモリリークが発生していたため、OracleはString.subString()最適化を削除しました。

  • アレイのコピーは高度に最適化されています。最新バージョンでは、JavaはSystem.arraycopyに手動で調整されたアセンブラを使用します。結果は、arraycopy / memcopy-heavy操作で、コードがCで同等のマージンを妥当なマージンで上回ることを確認しました。

  • JITコンパイラーは、L1 / L2キャッシュの使用に優れています。事前コンパイルされたプログラムは、コードをリアルタイムで微調整して、実行中の特定のCPUとシステムに適用することはできません。JITは、この方法で非常に効率的なループ変換を提供します。

「Javaは遅い」という評判に貢献した他のいくつかの歴史的事実:

  • JITコンパイル(Java 1.2 / 1.3)の前は、言語は解釈されるだけでコンパイルされていなかったため、非常に低速でした。
  • JITコンパイルが効率的になるのに時間がかかりました(各バージョンでの大幅な改善)
  • クラスローディングは、長年にわたってはるかに効率的になっています。以前は、起動時にかなり非効率で低速でした。
  • SwingとUIコードは、ネイティブグラフィックハードウェアをあまり使用していませんでした。
  • スイングはひどいです。Javaがデスクトップに追いつかなかった理由は、AWTとSwingのせいです。
  • ライブラリクラスでの同期の多用。非同期バージョンが利用可能になりました
  • 完全なJARをネットワーク経由で送信し、起動するVMをロードするため、アプレットのロードには永久に時間がかかります。
  • 同期は、パフォーマンスを大幅に低下させるために使用されていました(これは各Javaバージョンで最適化されています)。ただし、リフレクションは依然としてコストがかかります。

49
Object instantiation and object-oriented features are blazing fast to use (faster than C++ in many cases) because they're designed in from the beginning.そしてCollections are fast. Standard Java beats standard C/C++ in this area, even for most optimized C code.ここにリンクされた証拠によってサポートされていない野生の主張です。
Sjoerd、2011

8
@Sjoerd-クレームはワイルドではありません-それらは私には明白であり、C / C ++とJavaのデフォルトのメモリシステムのアーキテクチャの違いを理解している人なら誰にでもあるはずです。独自のメモリーハンドラー(フリーリスト、メモリープールなどを使用して)を作成するか、それを実装するライブラリーを使用すると、はるかに優れた処理行うことができます。
Rex Kerr

15
@Rex Kerr-割り当てにスタックなどを使用できるのに、なぜメモリハンドラを使用するのですか?ヒープメモリの割り当てとオブジェクトのインスタンス化を混同しています。
Sjoerd、2011年

20
@Rex Kerr-基本的に、Javaのすべてがヒープ上のメモリの割り当てを必要とし、Javaのヒープ上のJavaの割り当てはC ++の割り当てより速いため、Javaのすべてが速いと主張しています。ここにいくつかのニュースがあります:多くの場合、C ++ではヒープにメモリを割り当てることなく実行できます!
Sjoerd、2011年

10
@Sjoerd- Javaのすべてが高速だとどこで言ったのですか?私が言ったことを読んでください。私は私が意味することを言った、そしてあなたはあなたの最後のコメントであなたが言ったすべてにすでに対処した。
Rex Kerr、

49

当初、Javaはそれほど高速ではありませんでしたが、過度に遅くなることもありませんでした。最近、Javaは非常に高速です。私が話した人々から、Javaが遅いという印象は2つのことから来ています。

  1. VMの起動時間が遅い。初期のJava実装では、ネイティブアプリケーションと比較して、必要なライブラリとアプリケーションの起動とロードに長い時間がかかりました。

  2. UIが遅い。初期のスイングは遅かった。ほとんどのWindowsユーザーがデフォルトのMetal L&Fを醜く見つけたことも、おそらく役に立たなかったでしょう。

上記の点を考えると、「Javaは遅い」という印象を得たのは当然のことです。

ネイティブアプリケーション、またはVisual Basicアプリケーションの開発に慣れているユーザーまたは開発者にとって、これらの2つのポイントはアプリケーションで最も目に見えるものであり、それがアプリケーションについて得られる第一印象です(それが非GUIアプリケーションでない限り)。 1.のみ適用されます。

コードの実行と起動時間がまったく接続されていない場合でも、アプリケーションの起動に8秒かかるとすぐに起動する古いVisual Basicアプリケーションに対して、「コードを非常に速く実行する」ことをユーザーに納得させないでしょう。

第一印象を台無しにすることは、噂や神話を始めるための素晴らしい方法です。そして噂や神話を殺すのは難しい。

つまり、Javaは遅くありません。「Javaは遅い態度」を持つ人々は、10年以上前のJavaの第一印象に基づいています。


3
Javaは数年前は非常に低速でしたが、最近のベンチマークテストでは、C / C ++とほぼ同じ速度で実行され、状況によってはより高速に実行されます。
ChadNC、2010年

23
Macbook上のOSX 10.6上のJavaアプリは、Objective-Cで書かれたアプリよりも起動が非常に遅くなります。起動時間が短いことの証拠は何ですか?
Zan Lynx、

2
解凍は絶対にパフォーマンスの問題ではありません。私のコンピューターは1992年にプログラムを起動したときに実行可能ファイルを解凍しました。これにより、ハードドライブから長いファイルをロードするよりもパフォーマンスが向上しました。CPUとハードドライブ間の格差は、ここ数年で非常に大きくなっています。ただし、rt.jarにzipアーカイブ形式を使用すると問題が発生し(なぜ?!!!)、含まれているクラスファイルがリンクされません(nuts !!)。
トム・ホーティン-タックライン2010年

5
@Zan:Mac OS XのJVMはAppleによって書かれている(または少なくとも適応されている)ことに注意してください。Sunは、サポートするプラットフォーム(Windows、Linux、およびSolaris)で起動時間を短縮するためにかなりの時間を費やしましたが、Mac OS xでは(ポートを維持していないため)実行できませんでした。これは、Macは/ MacのOS Xに上/ポートすべてのそれらの最適化を適用していないことができなかったことかもしれない
ヨアヒム・ザウアー

1
私はJavaが遅いとは思っていません(私は、Javaでゲームを作っているゲームメーカーを知っています)。UIの理由でちょうど悪い。私が見た単一の「通常の」Javaアプリでは、まともな、完全に機能するUIはありません。
RCIX

40

Javaは遅くないというコメントが満載のページを読んだ後、私は異なる意見で答えなければなりません。

言語の遅さは、あなたの期待が「速い」ということに大きく依存しています。C#が高速であると考えるなら、Javaも確かに高速です。問題ドメインがデータベースまたは準リアルタイム処理に関連している場合、Javaも十分に高速です。ハードウェアを追加してアプリケーションを拡張できれば、Javaはおそらく高速です。5から10のスケールでの一定の要因によるスピードアップは、それほど価値がないと考えるなら、おそらくJavaを高速であると考えるでしょう。

大きなデータセットで数値計算を行う場合、またはCPUリソースが制限されている実行環境にバインドされている場合、5〜10のスケールで一定の高速化は非常に大きくなります。0.5スピードアップでも、計算が完了するまでに500時間の短縮を意味する場合があります。このような場合、Javaではパフォーマンスの最後のヤードを得ることができないため、Javaが遅いと考えられます。


2
同意し、有効なポイントを提示したため、投稿全体で+1しますが、たとえばC ++はデバッグが難しく、足全体を吹き飛ばしやすいという異なる特徴がありますが、C ++がそれほど遅くなることはほとんどありませんJavaについて聞いたように。
Stefano Borini、2010

33

あなたは2つのかなり異なる質問をしているようです:

  1. Javaは本当に遅いのですか、もしそうならなぜですか?
  2. Javaが他の多くの方法より高速であるにもかかわらず、なぜ低速であると認識されるのですか?

これらの最初の質問は、多かれ少なかれ「ロープの長さ」という種類の質問です。それはあなたの「遅い」の定義に帰着します。純粋なインタプリタと比較すると、Javaは非常に高速です。(通常)ある種のバイトコードにコンパイルされ、その後動的にマシンコードにコンパイルされる他の言語(たとえば、C#または.NET上の他のもの)と比較すると、Javaはおおよそ同等です。通常は純粋なマシンコードにコンパイルされ、(多くの場合)チームのオプティマイザ(C、C ++、Fortran、Adaなど)を改善する以外の何者もいない言語と比較すると、Javaはいくつかの点でかなりうまくいきますが、全体的に少なくとも多少遅くなる傾向があります。

これの多くは主に実装に関連しています-基本的に、それは動的/ JITコンパイラの実行中にユーザーが待機しているという事実に帰着します。そのため、最初からしばらく実行するプログラムがない限り、それはコンパイラーが困難な最適化に多くの時間を費やすことを正当化するのは困難です。したがって、ほとんどのJava(およびC#など)コンパイラーは、本当に難しい最適化に多くの労力を費やしません。多くの場合、どの最適化が適用されるかよりも、どの最適化が行われるかについては重要ではありません。多くの最適化問題はNP完全であるため、攻撃される問題のサイズに応じて、かかる時間は急速に増大します。時間を妥当な範囲に保つ1つの方法は、一度に1つの関数のようなものにのみ最適化を適用することです。コンパイラを待っているのが開発者だけの場合、より長い時間をかけて、同じ最適化をプログラムのより大きなチャンクに適用する余裕があります。同様に、いくつかの最適化のコードはかなり毛深いです(したがって、かなり大きくなる可能性があります)。繰り返しになりますが、ユーザーはそのコードがロードされる間待機しているため(JVMの起動時間は多くの場合、全体の時間の重要な要素です)、実装では、ある場所で節約される時間と別の場所で失われる時間のバランスをとる必要がありますやっかいな最適化のメリットは、JVMを小さく保つことの方が通常はより有益です。

2番目の問題は、Javaを使用すると、多かれ少なかれ「1つのサイズですべてに対応する」種類のソリューションが頻繁に得られることです。たとえば、多くのJava開発者にとって、Swingは基本的に利用可能な唯一のウィンドウライブラリです。C ++のようなものには、文字通り数十のウィンドウライブラリ、アプリケーションフレームワークなどがあり、それぞれに使いやすさと高速実行、一貫したルックアンドフィールとネイティブルックアンドフィールなどの間で独自の妥協点があります。唯一の本当の難点は、一部(たとえばQt)が非常に高価になる可能性があることです(少なくとも商用で使用する場合)。

第3に、C ++(さらにはC)で記述されたコードの多くは、単に古くて成熟しています。多くの場合、何十年も前に書かれたルーチンのコアが含まれていますが、コードの最適化に余分な時間を費やすことは通常の予想される動作でした。これは多くの場合、より小さくて高速なコードに実際の利点があります。C ++(またはC)は、コードが小さくて高速であることの功績を認められますが、それは実際には、開発者の製品であり、コードが書かれた時間の制約です。ある程度、これは自己実現的な予言につながります-人々がスピードを気にするとき、彼らはその評判があるので彼らはしばしばC ++を選択します。彼らは余分な時間と労力を最適化に費やし、新世代の高速C ++コードが書かれています。

要約すると、Javaの通常の実装では、最大限の最適化がせいぜい問題になります。さらに悪いことに、Javaが表示される場合、ウィンドウツールキットやJVMの起動時間などは、言語自体の実行速度よりも大きな役割を果たすことがよくあります。多くの場合、CとC ++は、最適化に一生懸命取り組んだ結果として実際に何が得られたのかについても評価されます。

2番目の質問については、それは主に仕事での人間の本性の問題だと思います。いくつかの熱心な人々は、Javaが盲目的に高速であることについてかなり膨らんだ主張をしています。誰かがそれを試してみると、些細なプログラムでさえ、開始するのに数秒かかり、実行すると遅くて不器用に感じます。これの大部分がJVMの起動時間であることに気づくために物事を分析する人はほとんどいません。そして、彼らが最初に物事を試したとき、コードはまだコンパイルされていません-コードの一部は解釈されています。そして、彼らが待っている間にコンパイルされているものもあります。さらに悪いことに、実行速度が十分であっても、ルックアンドフィールは通常、ほとんどのユーザーにとって異質で不格好に見えるため、客観的な測定で高速な応答時間が示されても、不格好に見えます。

これらを一緒に追加すると、かなり単純で自然な反応になります。Javaは遅く、醜く、不器用です。それが本当に速いと言っている誇大宣伝を考えると、(より正確な)「少し遅い、そしてそれは主に特定の状況下で」というよりは、反応がひどく遅くて、ひどく遅いと考える傾向がある。これは一般的に、言語で最初のいくつかのプログラムを作成する開発者にとっては最悪です。ほとんどの言語で「hello world」プログラムの実行は瞬時に表示されますが、Javaでは、JVMの起動時に簡単に認識できる一時停止があります。タイトなループで実行速度がはるかに遅い純粋なインタープリターでさえ、ロードされて少し早く実行を開始できるという理由だけで、このようなコードの方が高速に表示されることがよくあります。


16

これは、Javaの初期(1990年代半ばから後半)の古い情報です。Javaのすべてのメジャーバージョンは、以前のバージョンと比較して大幅な高速化を実現しています。OracleがJRockitをSunのJVM for Java 7とマージしているようで、この傾向は今後も続くと思われます。

他の多くの人気のある現代の言語(Python、Ruby、PHP)と比較して、Javaは実際にはほとんどの用途で大幅に高速です。CやC ++とは完全には一致しませんが、多くのタスクでは十分に近いです。実際のパフォーマンスの問題は、最終的にどれだけのメモリを使用するかということです。


14

「長い起動時間」の主な原因は動的リンクです。Javaアプリケーションは、コンパイルされたクラスで構成されています。各クラスは他のクラス(引数の型、メソッドの呼び出しなど)を名前で参照します。JVMは起動時にこれらの名前を調べて一致させる必要があります。これは段階的に行われ、常に必要な部分のみを実行しますが、それでもまだやるべき作業です。

Cアプリケーションでは、そのリンクフェーズはコンパイルの最後に発生します。特に大きなアプリケーションの場合、処理速度は遅くなりますが、開発者にしか見えません。リンクすると、OSがRAMに「そのまま」単にロードする必要がある実行可能ファイルが生成されます。

Javaでは、アプリケーションが実行されるたびにリンクが発生します。したがって、起動時間が長くなります。

キャッシング手法を含むさまざまな最適化が適用され、コンピューターはより高速になり(そして、アプリケーションが「より大きく」なるよりも「より速く」)、問題の重要性は最近大幅に減少しています。しかし、古い偏見は残っています。

その後のパフォーマンスについては、配列アクセス(主にハッシュ関数とその他の暗号化アルゴリズム)を使用したコンパクトな計算に関する私自身のベンチマークは、通常、最適化されたCコードがJavaコードの約3倍高速であることを示しています。実装されているアルゴリズムによっては、CはJavaよりも30%高速な場合と、4倍高速な場合があります。プロセッサが提供する64x64-> 128の乗算オペコードが原因で「C」コードが実際に大きな整数演算用のアセンブリであるときに10倍の因子を見たが、Javaはその最長の整数型が64ビットであるため使用できないlong。これはエッジケースです。実際の条件下では、I / Oとメモリ帯域幅の考慮事項により、CコードがJavaよりも実際に 3倍高速になることはありません。


うーん...最近のほとんどのCライブラリも動的にリンクされていると思いました。それとも何か違うことを話しているのですか?
Sean McMillan

4
@Sean:Cの動的リンクは「外部シンボル」に対して発生します。あるDLLで使用され、別のDLLで定義される関数です。典型的なCアプリケーションは、ダースDLLを使用します。Javaの場合、動的リンクはすべてのクラスのすべてのメソッドで発生します。標準的なJavaアプリケーション(標準ライブラリを含む)には、何千ものメソッドがあります。Cの世界では、ほとんどのリンク(DLLの境界を越えないすべてのリンク)はコンパイル時に解決されますが、実行時に実行する必要があるのはごくわずかです。
Thomas Pornin

14

特に量的な作業では、Javaは明らかに遅いです。

R、Python、C / C ++と最適化されたマルチスレッドATLASライブラリを組み合わせて使用​​しています。これらの各言語では、約4秒で、3000倍の3000倍の行列を行列乗算できます。JavaでColtとParallel Coltを使用すると、同じ操作に185秒かかります。これらのJavaライブラリは本質的に並列であるにもかかわらず、驚くべきものです。

したがって、全体として、純粋なJavaは定量的な作業には適していません。JLASはATLASを使用しているため、Javaの最良の線形代数ライブラリーのようです。

私のマシンは3 GBのRAMを搭載したHP Core 2 Duoです。64ビットのUbuntu 10.04(Lucid Lynx)を使用しています。


前述のコメントに続き、私はJAMAを使用して同じ行列乗算演算を実行し、約50秒かかりました。他の言語に比べるとまだ遅い。
ハマードシャー

7
JNI経由で呼び出されるライブラリーで乗算を実行したとき、Javaはどれくらいの時間を要しましたか。C / C ++で実行できるすべてのことを考えると、JNIで実行できる(数百ナノ秒を追加する)と、マージンは比較的小さくなります。私はあなたのRとPythonの行列乗算がRやPythonで書かれておらず、それらの言語から呼び出されただけだと思います。
Peter Lawrey、

2
好奇心から、コードにホットスポット(型変換/オートボクシング)があるかどうかを特定するためのプロファイリングを行いましたか?
–ThorbjørnRavn Andersen 2012

10

ほとんどの人にとって、Javaの操作経験遅いです。アプレットが表示される前に、ブラウザでコーヒーカップが回転しているのを見てきました。JVMを起動してアプレットバイナリをダウンロードするにはしばらく時間がかかります。これは、ユーザーエクスペリエンスに気づくように影響します。

遅いJVMスピンアップとアプレットのダウンロード時間がJavaコーヒーカップで目立つようにブランド化されていることは役に立たないので、人々は待機をJavaと関連付けます。Flashの読み込みに時間がかかる場合、「読み込み中」メッセージのブランドはFlash開発者が指定するため、Flashテクノロジ全体を非難する必要はありません。

これはすべて、サーバー上でのJavaのパフォーマンスとは関係がなく、Javaがブラウザーの外で使用される他の多くの方法でも関係ありません。しかし、それは人々が目にするものであり、Java以外の開発者がJavaについて考えるときに覚えていることです。


9

Javaは遅いため、遅いという評判があります。Javaの最初のバージョンでは、ジャストインタイムのコンパイルがまったくなかったか、不十分でした。これは、コードがバイトコードであるにもかかわらず解釈されていたため、最も単純な演算(2つの整数の加算など)でも、マシンはあらゆる種類の比較とポインタ逆参照および関数呼び出しを実行する必要があったことを意味します。JITコンパイラーは常に改良されています。今では、C ++コードを不注意に、Javaコードを不注意に書いた場合、JITコンパイラーが不必要なポインターの逆参照を取得し、それを処理してくれるので、JavaがC ++ より優れていることがあります。

JITコンパイルの違いの大きさを知りたい場合は、Computer Languages Benchmark Gameで解釈済みベンチマークと非解釈ベンチマークを確認してください。(Pidigitsは外部ライブラリを使用してすべての計算を行うので、ベンチマークは変更されません。他のものは6〜16倍のスピードアップを示します!)

それが主な理由です。問題を解決しなかった、他にもさまざまな理由があります。最初は、Javaの起動時間が遅かった(現在は修正されています)。JavaのWebアプリのダウンロードには時間がかかります(ブロードバンドが広くアクセスできるようになり、映画などの大規模なものが期待されるようになったため、今ではあまり当てはまりません)。UI Swingはパフォーマンスを念頭に置いて作成されていません(まだ作成されていません)ので、C ++などの同等のものよりもはるかに簡単です。


6

Java WASは遅く、昔に戻りました。数世代のパフォーマンス強化により、処理速度が大幅に向上しました。最後に聞いたところ、通常はC#の速度の10%以内です。

クラス全体をロードする必要のあるJVM全体を起動する必要があるため、Javaアプレットの起動は依然として遅い。別のコンピュータを起動するのと似ています。JVMが起動すると非常に高速になりますが、通常、起動は人々が覚えていることです。

また、Javaの実行可能性を決して信じない人少なくありません。


1
残念ながら、JVMの起動はCLRの起動よりもはるかに低速です。これは、SunがJava 7のリリースで最悪の方法で足を引っ張ったため、4年前の Java 6 への増分パッチで立ち往生している
BobMcGee 2010年

3
うわー、Java 6は4歳ですか??? うん、そうだと思う(ベータを数えるなら)。それでも私は新しいと感じています-職場で1.4の使用をやめました。
Kaleb Brasee 2010年

Java 1.4は使用可能ですが、1.5と1.6でパフォーマンスが大幅に向上し、構文上の砂糖が追加されたため、ちょっと変わっています。その後、境界チェックとSystem.arraycopy最適化が導入されました。同期が大幅に改善されました。1.4は本当に遅いと言っても差し支えないと思います。
BobMcGee 2010年

LOL、わかっています-手動でイテレートしたり、ジェネリックリストの代わりにアレイを使用したりするたびに、ラップトップを半分にしたいと思います... IBMは実際、何年もの間、WAS 6.1でJava 5を利用できましたが、 WAS 6.0で立ち往生している:(私はそれが私自身のもののために出て以来、Java 5/6を使用していますが、作業中の古いサーバーバージョンによって制限されています。1.4から最新バージョンへの2桁のパーセントのパフォーマンス改善があります。たくさんのために、と私はそれらを楽しみにしています。
Kaleb Brasee

6

ステファノ:

私は最初からJavaを使用していたので、私の見解では、低速であるという名声は、応答が遅く低速のGUIフロントエンド(AWT、次にSwing)によって、またアプレットで作成されました。 VM。

JavaはVM領域で多くの研究を規定および推進しており、ガベージコレクション(実際には多くのことを調整できますが、デフォルトのみが使用されているシステムをよく見かけます)やホットスポットなど、かなりの改善がありました。最適化(これは最初、おそらくまだサーバー側でより効率的です)。

バックエンドのJavaと計算レベルはそれほど遅くありません。コルトは最高の例の1つです。

最新の安定したColtリリースは、JDK ibm-1.4.1、RedHat 9.0、2x IntelXeon@2.8 GHzで1.9 Gflop / sの壁を破ります。

リアルタイムJavaやJavolutionのような速度を向上させる特別なメカニズム、Ahead-Of-Timeコンパイル(gcjなど)のように、考慮すべきメインストリームJava以外の多くのものがあります。また、Java Bytecodeを直接実行できるICもあります。たとえば、現在のiPhoneやiPodのARM Jazelleにあるようなものです。

今日では一般的に、それは政治的決定(iPhone / iPodでJavaがサポートされないなど)であり、言語としてのJavaに対する決定である(多くの人がそれは冗長すぎると考えるため)と思います。

ただし、Java VMには現在、他の多くの言語(Python、Ruby、JavaScript、Groovy、Scalaなど)があります。

個人的には、優れたツールとライブラリーの可用性を備えた柔軟で信頼性の高いプラットフォームとして引き続き楽しんでおり、最小のデバイス(例:JavaCard)から最大のサーバーまですべてを扱うことができます。


OK、それで、GUIツールキットから別の悪い評判が出ました。もちろん、現代のJVMはネイティブウィジェットを使用しているため、OSライブラリにフックしていると思います。または、AWT / Swingを使用して、ホストプラットフォームと同じルックアンドフィールをレンダリングしますか?
Stefano Borini、2010年

ステファノ:Swingは実際にはウィジェットのネイティブではないユニバーサルレンダリングの考え方に基づいているため、仮定はちょっと間違っています。これは実際に、Swingコンポーネントがネイティブコンポーネントの外観をエミュレートできるようにする「プラグイン可能なルックアンドフィール」メカニズムです。そのようなものを探している場合は、SWT(eclipse.org/swt)をチェックして、ネイティブOSにフックして、JNI(ボトルネックと言われている)を使用してネイティブウィジェットを使用することができます。
Dieter、

Java2D(Swingに使用)は最近非常に高速であり、ネイティブウィジェット(SWT)を使用してもパフォーマンス上の利点はありません。少なくとも、6か月前にSwingとSWTのどちらを学ぶかを決めるときに読んだことは、これです。
Luigi Plinge、2011年

4

ハンマーは、他の多くのツールよりも生地のロールアウトがはるかに遅いです。ハンマーを「遅く」したり、ハンマーが行うように設計されているタスクに役立たなくなったりすることはありません。

一般的なプログラミング言語として、Javaはさまざまなプログラミングタスクの多く(ほとんどではないにしても)と同等です。「金属に近い」より洗練されていない言語では、Javaが手動でコーディングしたソリューションよりもパフォーマンスが優れていない、特定の簡単なテストがあります。

しかし、「現実世界のアプリケーション」に関しては、Javaが適切なツールであることがよくあります。とはいえ、開発者がANYツールを使用してパフォーマンスの遅いソリューションを作成するのを妨げるものは何もありません。ツールの誤用はよく知られている問題です(PHPとVBの評判を見てください)。ただし、Javaの(ほとんど)クリーンな設計と構文は、誤用を減らすのに役立ちます。


3

Javaは高水準言語であり、その評判は今日、他の同等の高水準言語と同等のパフォーマンスを持つことです。

  1. それは持っている動的バインディングセマンティクスを。非仮想メソッドが関数呼び出しとしてコンパイルされるC ++と比較すると、世界最高のJavaコンパイラでさえ、効率の悪いコードを生成する必要があります。しかし、それはまた、よりクリーンで、より高レベルのセマンティクスでもあります。

  2. 詳細は覚えていませんが、Javaの初期の頃には、Javaオブジェクトごとにmutexがあり、各メソッドによって取得および解放されると聞きました。残念ながら、オブジェクトごとのミューテックスだけでは、競合やデッドロック、または並行プログラムで発生する可能性のある悪いことからユーザーを保護することはできません。その部分は、もし真実であれば、少し素朴ですが、それは善意から来ました。この側面について詳しく知っている場合は、詳細を自由に記入してください。

  3. Javaが高水準言語であるもう1つの方法は、Garbage-Collectionを使用することです。ガベージコレクションは、より遅くなる場合がありmallocおよびfreeそれにすべての彼らが必要とするメモリ、ワーク一度に割り当てるプログラムのため。問題は、ガベージコレクションを持たない言語では、プログラマーは必要なすべてのメモリを一度に割り当てるプログラムのみを作成する傾向があり、任意の最大サイズ定数がオーバーフローした場合に失敗することです。したがって、比較はリンゴとオレンジです。プログラマーが非GC言語で連鎖構造を動的に割り当ててプログラムを作成およびデバッグしようとすると、プログラムがGC言語よりも高速ではなくなっていることがmallocあります。free無料ではありません!それらにはオーバーヘッドもあります...加えて、誰が何を解放するかを指定するGCの強制がなく、いつ誰が何を解放するかを指定しなければならないこともあります。最後に使用しますが、GC言語ではコピーは必要ありませんでした。


1.おそらくHotSpotには当てはまりません。2.メソッドを同期済みとしてマークした場合のみ。
Winston Ewert

1
1.コンパイラーはコードを最適化しませんが、JVMは1つまたは2つの仮想メソッドのみが動的に呼び出されることを動的に決定するのに十分スマートであり、静的に呼び出すことも、インラインで呼び出すこともできます。C ++では仮想メソッドをインライン化できないと確信しています。2.すべてのJavaオブジェクトにはロックがあります。各オブジェクトに小さなオーバーヘッド(約1バイト)がありますが、使用しない場合の影響はほとんどありません。3. Javaでは、必要なすべてのオブジェクトを一度に割り当てることができます。これにより、1日中GCを実行しないアプリケーションを作成できます。;)JavaのGCは暗黙的にマルチスレッド化されており、C ++で特別なライブラリを必要とします。
Peter Lawrey、

C ++は仮想呼び出しをインライン化できますが、Javaはより多くの場合にそれを実行でき、メガモーフィックな呼び出しサイトを最適化することでより強力になります。
PiotrKołaczkowski15年

2

90年代半ばにJavaが主流になったとき、C ++が主流の言語であり、ウェブはまだかなり新しいものでした。また、JVMとGCは主流の開発における比較的新しい概念でした。初期のJVMは(ベアメタルで実行されているC ++に比べて)少し遅いし、ガベージコレクションの一時停止が長いこともあり、Javaの評判が遅いという結果になりました。


これはGCの背後にあるテクノロジーによるものですか?GCフェーズでより効率的になるための戦略(オブジェクトの世代別レイヤーなど)があることは知っています。その時の戦略は何でしたか?
Stefano Borini、2010年

1
IANA JVMエキスパートですが、当時はGCにシングルスレッドのマーク/スイープアルゴリズムが使用されていたため、GCの実行中にJVM全体を一時停止する必要がありました。現在、並行マーク/スイープがあり、JVMには他にも多くのパフォーマンス強化があります。
Ken Liu

2
最新のGCアルゴリズムは優れていますが、最大の改善点はJITだったと思います。
Pascal Thivent、2010年

1

多くのJavaデスクトップアプリ(今回はEclipseなど)はGUIの応答性がよくありません。これは、メモリの消費量が多く、クラスローダーが大量のIOを実行できるためと思われます。それは改善していますが、数年前に悪化しました。

多くの(ほとんどの)人々は、一般化を行うことを好み、「Javaは遅い」と言います。


高いメモリ消費はツールまたはJavaライブラリから発生すると思いますか?
Stefano Borini、2010

Eclipseの場合-Eclipseインフラストラクチャ自体から。過去の「重い」GUIでも同じです(私が覚えているようにJBuilder)。静的に型付けされた言語でプラグインアーキテクチャ(Eclipseなど)を使用するには、多くのボイラープレートオブジェクトが必要なためです。Emacsにもプラグインがあり、通常のコーディングを行う場合のメモリ消費量はEclipseの10〜20分の1です。Emacs Lispコードはバイトコードにコンパイルされ、emacsインスタンスにロードされて実行されます-Javaクラスローダーに似ています。Javaでは、プラグインを可能にするためにインスタンス化された中間オブジェクトがたくさんあると思います。
Wojciech Kaczmarek、2010

1

Javaアプリケーションの主な問題は、ストックランタイムライブラリのサイズが大きいために巨大になることです。巨大なプログラムはメモリを大量に使用し、スワップする傾向があります。つまり、プログラムが遅くなります。

Sun JVMが大きい理由は、多くのことを追跡することによって機能する非常に優れたバイトコードインタープリターがあるためです。それは多くのデータ、つまりメモリを意味します。

かなり高速なインタープリター(ネイティブコードなし)で非常に小さいjamvm仮想マシンを確認することをお勧めします。それも速く起動します。


1

パスカルが言うように、Javaは他の高水準言語と同等です。ただし、Windows 98で元のJVMを操作した人としてで、当時、Java仮想マシンによって提供される抽象化のレベルは苦痛でした。

基本的に、今日のJVMで当たり前とされているのは、ほとんどまたはまったく最適化されていないソフトウェアエミュレーションでした。


0

人々は通常、「それは解釈された」行を腐敗させます。むかしむかし、そうだったし、Javaを「遅すぎる」とダンプし、新しいバージョンをテストするために戻ることのない人々から悪い報道が伝わってきたからだ。

あるいは、「人は馬鹿である」がより良い答えかもしれません。


0

いつか、近い将来ではないかもしれませんが、JITコンパイラはランタイムを大量に使用する可能性があるため、JITコンパイル言語はあらゆる面でコンパイル言語よりも優れています(おそらく、起動時間/メモリ消費ではありません)。動作とそれらが実行されているプラ​​ットフォーム。


6
私はあなたが何を考える意味そのJITコンパイル(ない解釈される)コードがAOTコードを負かす事になりますされると言うこと。解釈は、コンパイルされたコードを実行するよりも常に遅くなります。これが、JITコンパイラが使用される理由です。キャッチ:事前コンパイラとJITコンパイラの出力にはほとんど違いがありませんが、JITコンパイラはより速くコンパイルする必要があり、ランタイム情報を使用して最適化のヒントを得ることができます。プラットフォーム固有の最適化を備えたプラットフォーム固有のAoTコンパイラーは、最適化に費やす時間に制限がないため、ほとんどの場合JITに勝ります。
BobMcGee 2010年

答えてくれてありがとう。JITコンパイラーが自由に使える時間について考えたことはありませんでした。
ヘルパーメソッド2010年

つまり、ホットスポットの適応最適化のようなものですか?
Stefano Borini、2010年

2
@BobMcGee:そうですね。C ++プログラムは、すべての操作のプロファイルフィードバックを使用して実行速度が遅くなるように構築できます。その後、コンパイラーは、30分のCPU時間と2 GBのRAMを使用して、非常に高速なバージョンを自由に再構築できます。これを行ったJITは、ユーザーを去らせます。
Zan Lynx、2011

1
JITコンパイル時間は、サーバーなどの長時間実行されるアプリでは無視できます。PGOでのAOTは、少なくとも2つの理由で、JITに比べて制限されています。まず、ほとんどのパフォーマンスの違いは、軽量の最適化によって達成されます。gcc -O2とgcc -O3を比較してください。ほとんどの場合違いはありません。- O3の方が少し良い場合もあれば、少し悪い場合もありますが、これと2倍を超える差はありませんでした。第2に、PGOでもAOTを使用すると、使用サイトでのプロファイルが何であるかしか推測できません。間違っていると思います。JITに大きく遅れています。また、実際のプロファイルは、構成に大きく依存する場合があります。
PiotrKołaczkowski15年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.