Java プログラミング言語で最もコストのかかる (バイトコードと CPU サイクルの両方の点で) ステートメントは何ですか?
6 に答える
どの言語でも、さまざまなステートメントを何度も実行し、どれくらいの時間がかかるかを見ることで、さまざまなステートメントの速度を知ることができます。あなたの質問はそれよりも賢いと思います。たとえば、このシナリオでは、いくつかのチューニング手順が実行され、各手順で別の何かが主要な問題でした。
最初のステップ: 時間のかかる主な要因は、反復子をインクリメントすることと同等でした。(直しますか? 整数インデックスを使用してください。)
それを修正した後、問題はリンクされたリストを一度に 1 つの要素で構築することでした。(解決しますか?一度にすべてをビルドします。)
再設計後の主な問題は、オブジェクトのストレージの割り当てと解放でした。(直しますか? 使用済みオブジェクトを再利用します。)
各段階で、いくつかの問題が最大です。それを修正した後(そしてかなりのスピードアップを得た後)、他のいくつかの問題が新たに最大のものになりました。それを修正した後...(最大の問題が何であるかがわかるまで、そしてそれを修正することはできません)。
ほら、「どのステートメントが最も高価か」とはほとんど関係がありません。あるステートメントが絶対に実行する必要があることを行っており、それを行うためのより良い方法が見つからない場合、定義上、そのステートメントはその仕事に最適なステートメントです。
これには簡単な答えはありません。VM と基盤となるハードウェアによって異なります。使用している VM は、おそらくバイト コードをマシン コードにコンパイルするため、問題は、ハードウェアで最もコストのかかるアセンブリ コールはどれかということです。
古典的に最悪だったのは、計算に関する分割でした。しかし、最近の計算は安価であり、メモリは遠く離れています。そのため、最新のハードウェアで最もコストのかかる呼び出しは、キャッシュにアクセスできないメモリ アクセスです。メイン メモリにアクセスするには、500 ~ 1000 の CPU サイクルが必要です。
したがって、次のような行です。
x++;
... x がキャッシュからプッシュされた場合、数百サイクルかかる場合があります。これの最も一般的な例は、メモリ内にあるリンクされたリストをトラバースすることです。
for (ListElement n = ...; n != null; n = n.next()) { n.val++; }
ここで、呼び出しn.next()
は毎回 500 ~ 1000 サイクルかかることがあります。これは、リンクされたリストがシステム メモリ内でまばらに分散される可能性があるためです。
おそらく、少なくとも CPU サイクルの場合、例外処理。
sleep() は最もコストのかかるものの 1 つに違いないと思います! ;)
あなたの質問には詳細が必要です。いつでも書ける
while(true) {}
そして、CPU サイクルを際限なく消費します。どのような種類のステートメントについて話しているのですか?
System.out への呼び出しのようにコードをシリアル化する IO または何かを含むもの。
CPUサイクルに関して:
public class Zombie extends Thread {
public void run() {
while (true)
{(new Zombie()).start();}
}
public static void main(String args[]) {
(new Zombie()).start();
}
}
確かに単一のステートメントではありませんが、here から借用して翻案しました。
OP、BCELプロジェクトを見てください。Java ByteCodeの詳細を学ぶために、興味があるかもしれません。