[解決済み] Javaは本当に遅いのか?
質問
Javaは 遅いという評判がある程度 .
- Javaは本当に遅いのか?
- はい」の場合、その理由は?ボトルネックはどこですか(または、どこでしたか)?非効率なJVMが原因ですか?ガーベッジコレクションですか?JNIでラップされたCコードではなく、純粋なバイトコードライブラリ?他の多くの言語にはこれらの機能がありますが、遅さについてのこのような評判はありません。
どのように解決するのか?
現代のJavaは、メモリを大量に消費するものの、最も高速な言語の1つです。Java があった。 は、VMの起動に時間がかかるため、遅いと評判でした。
まだJavaが遅いと思っている方 をご覧ください。 ベンチマークゲーム の結果です。 先読みコンパイル言語(C、Fortranなど)で書かれた、厳密に最適化されたコードは、Javaに勝つことができますが、Javaは、PHP、Ruby、Pythonなどと比べて10倍以上速くなることがあります。一般的なコンパイル言語(標準ライブラリを使用する場合)に勝てる特定の領域があります。
Javaアプリケーションはもう遅いという言い訳は通用しません。 言語よりも、開発者やレガシーコード/ライブラリの方がはるかに責められるべきでしょう。また、「エンタープライズ」なものにも責任があります。
Javaは遅い」という意見に配慮し、Javaがまだ遅い分野を紹介します(2013年最新版)。
-
ライブラリはしばしば、パフォーマンスではなく、正確さや読みやすさを重視して書かれます。 私見ですが、これがJavaが特にサーバーサイドでいまだに評判が悪い主な理由だと思います。このため、Stringの問題は指数関数的に悪化しています。単純な間違いもよくあります。プリミティブの代わりにオブジェクトが使われることが多く、パフォーマンスが低下し、メモリ使用量も増えています。多くのJavaライブラリ(標準的なものを含む)は、mutableやより単純なフォーマット(char[]やStringBuffer)を再利用するのではなく、頻繁にStringを生成します。これは遅いし、後で回収するゴミが大量に発生します。これを解決するために、開発者は可能な限りプリミティブコレクション、特にJavalutionのライブラリを使用することをお勧めします。
-
文字列の操作が少し遅い。 Javaはimmutableを使用しています。 UTF-16 -エンコードされた文字列オブジェクトです。つまり、ASCII(C、C++)に比べ、より多くのメモリが必要で、メモリアクセスも多く、一部の操作が複雑になります。当時は 右 ポータビリティのための決断ですが、わずかながらパフォーマンスの犠牲を伴います。 UTF-8 のほうがよさそうです。
-
C言語と比較して、配列アクセスが若干遅くなります。 境界チェックのためです。以前はこのペナルティは大きかったのですが、現在は小さくなっています(Java 7は多くの冗長な境界チェックを最適化して取り除いています)。
-
任意のメモリアクセスができないため、一部のI/Oやビットレベル処理が遅くなることがあります(例えば圧縮/解凍)。 これは現在、ほとんどの高級言語が備えている安全機能です。
-
JavaはC言語よりも多くのメモリを使用します。 で、アプリケーションがメモリに縛られていたり、メモリ帯域に縛られている場合(キャッシュなど)、動作が遅くなります。裏を返せば、アロケーション/デアロケーションが非常に速い(高度に最適化されている)ということです。 これは、現在ほとんどの高級言語の特徴であり、オブジェクトや使用により GC は、明示的なメモリ割り当てではなく それにライブラリの判断も悪い。
-
ストリームベースのI/Oが遅い 各ストリームアクセスに同期を必要とする(IMO、貧しい選択)ためです。 NIO はこれを修正しましたが、使うのは面倒です。一度に1つの要素ではなく、配列に対して読み書きを行うことで、この問題を回避することができます。
-
JavaはCのような低レベルの機能を提供しない。 そのため、インラインアセンブラの汚い技を使って、ある操作を高速化することはできないのです。 これは移植性を高めるもので、今ではほとんどの高級言語が備えている機能です。
-
非常に古いバージョンのJVMに縛られているJavaアプリケーションをよく見かけます。 特にサーバーサイド。これらの古いJVMは、最新バージョンと比較すると、信じられないほど非効率的です。
結局のところ、Javaはパフォーマンスをある程度犠牲にして、セキュリティと移植性を提供するように設計されており、本当に要求の厳しい操作にはそれが表れているのです。遅いという評判のほとんどは、もはや値しないものです。
しかし、いくつかの場所では、Javaが より速く 他のほとんどの言語よりも
-
メモリの確保と解放 は、高速かつ安価です。 私が見たケースは の方が20%速い(あるいはそれ以上!)。 数kBの配列を新たに確保する方が キャッシュされたものを再利用する
-
オブジェクトのインスタンス化とオブジェクト指向の機能は、驚くほど高速に使用することができます (場合によってはC++より速い)。なぜなら、これらは最初から設計されているからです。 これは、部分的には、明示的なアロケーションではなく、優れたGCによるものです(これは、たくさんの小さなオブジェクトのアロケーションに対してより親切です)。Cでもこれに勝るコーディングは可能ですが(カスタムメモリ管理を行い、mallocを効率的に行うことで)、簡単なことではありません。
-
メソッド呼び出しは基本的に無料であり、場合によっては大規模なメソッドコードよりも高速になります。 その ホットスポット コンパイラは、実行情報を利用してメソッド呼び出しを最適化し、非常に効率的なインライン化を実現します。実行情報を利用することで、先読みコンパイラや(まれに)手動インライン化よりも優れた性能を発揮することもある。C/C++では、コンパイラがインライン化しないことを決定した場合、メソッドコールにわずかな性能ペナルティが発生するのと比較されます。
-
同期とマルチスレッドが簡単で効率的です。 Javaは最初からスレッドを意識して設計されており、それが表れています。最近のコンピュータはマルチコアを搭載しているのが普通ですが、Javaにはスレッド機能が組み込まれているので、非常に簡単に利用することができるのです。基本的に、標準的なシングルスレッドCコードと比較して、100%から300%のスピードアップが可能です。 確かに、C言語のスレッド処理とライブラリを注意深く書けばこれに勝てるのですが、プログラマーにとっては余計な仕事が増えることになります。
-
文字列は長さを含む:いくつかの操作が高速化されます。 これは、NULL区切りの文字列(C言語では一般的)を使用するよりも優れています。Java 7では、OracleはString.subString()の最適化を削除しました。なぜなら、人々が愚かな使い方をしてメモリリークを起こしたからです。
-
配列コピーは高度に最適化されています。 最新のバージョンでは、JavaはSystem.arraycopyのためにハンドチューニングされたアセンブラを使用しています。その結果、配列コピーやメモリコピーを多用する操作において、私のコードはCの同等品に妥当なマージンをもって勝っているのを見た。
-
JIT コンパイラは L1/L2 キャッシュ . 先読みコンパイルされたプログラムは、実行中の特定のCPU & システムにリアルタイムでコードを微調整することができません。JITはこのように非常に効率的なループ変換を提供します。
Javaは遅いという評判には、他にもいくつかの歴史的事実があります。
- JITコンパイル(Java 1.2/1.3)以前は、コンパイルではなく解釈のみであったため、非常に遅い言語でした。
- JITコンパイルが効率的になるまでに時間がかかった(バージョンアップごとに大きな改善あり)
- クラスローディングは、ここ数年で、かなり効率化されました。以前はかなり非効率で、起動時に時間がかかっていました。
- スイング とUIコードは、ネイティブのグラフィックハードウェアをうまく利用できていませんでした。
- Swingはとにかくひどい。 Javaがデスクトップ向けに普及しなかったのは、AWTとSwingのせいだと思います。
- ライブラリクラスで同期を多用、非同期版も登場
- アプレットのロードに時間がかかる。 JAR をネットワーク上で実行し、VM をロードして起動します。
- 同期には大きなパフォーマンスペナルティがありました(これはJavaの各バージョンで最適化されています)。しかし、リフレクションはまだコストがかかる。
関連
-
をインスタンス化することができません。
-
Exception: java.util.NoSuchElementException: 行が見つかりません
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み】Javaの「ダブルブレース初期化」の効率化?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
スレッド "main "での例外をEclipseで解決 java.lang.Error: 未解決のコンパイル問題、コンパイラとパッケージの不整合
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
プロジェクトの依存関係を解決できなかった 解決
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
javaでよく使われる英単語
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
HttpClientがGZIP形式でない場合の対処法
-
このラインで複数のマーカーを解決する方法
-
コミットには何も追加されないが、未追跡のファイルが存在し、gitで未追跡のファイルに対する完璧な解決策