1

Recently someone told me that a comparison involving smaller integers will be faster, e.g.,

// Case 1
int i = 0;
int j = 1000;
if(i<j) {//do something}

// Case 2
int j = 6000000;
int i = 500000;
if(i<j){//do something else}

so, comparison (if condition) in Case 1 should be faster than that in Case 2. In Case 2 the integers will take more space to store but that can affect the comparison, I am not sure.

Edit 1: I was thinking of binary representation of i & j, e.g., for i=0, it will be 0 and for j=1000 its 1111101000 (in 32-bit presentation it should be: 22 zeros followed by 1111101000, completely forgot about 32-bit or 64-bit representation, my bad!)

I tried to look at JVM Specification and bytecode of a simple comparison program, nothing made much sense to me. Now the question is how does comparison work for numbers in java? I guess that will also answer why (or why not) any of the cases will be faster.

Edit 2: I am just looking for a detailed explanation, I am not really worried about micro optimizations

4

3 に答える 3

3

パフォーマンスが気になる場合は、コードがネイティブ コードにコンパイルされたときに何が起こるかを考えるだけで十分です。この場合、重要なのは CPU の動作です。単純な操作では、ほとんどすべての CPU が同じように動作します。

そのため、ケース 1 の比較 (if 条件) はケース 2 よりも高速である必要があります。ケース 2 では、整数を格納するためにより多くのスペースが必要になりますが、それが比較に影響を与える可能性があるかどうかはわかりません。

Anintは Java では常に 32 ビットです。これは、常に同じスペースを取ることを意味します。いずれにせよ、データ型のサイズはそれほど重要ではありません。たとえばshort、ネイティブ ワードのサイズが 32 ビットまたは 64 ビットであり、より大きな型から適切なデータを抽出して符号拡張する必要があるため、byteしばしば遅くなります。 .

JVM仕様と単純な比較プログラムのバイトコードを見てみましたが、あまり意味がありませんでした。

JLS は、パフォーマンス特性ではなく、動作を指定します。

問題は、Java で数値の比較がどのように機能するかです。

他のほぼすべてのコンパイル済み言語と同じように機能します。1 つのマシン コード命令を使用して 2 つの値を比較し、別のマシン コード命令を使用して、必要に応じて条件分岐を実行します。

それは、どのケースでも高速になる理由 (またはそうでない理由) にも答えると思います。

最近のほとんどの CPU は分岐予測を使用します。CPU のパイプラインをフルに保つために、どの分岐が実行されるかを予測しようとします (それが正しい分岐であることがわかる前に)。そのため、実行された命令が途切れることはありません。これがうまく機能する場合、ブランチのコストはほとんどかかりません。予測を誤った場合、パイプラインは、間違った推測であった分岐の命令でいっぱいになる可能性があり、パイプラインをクリアして正しい分岐を取るため、大幅な遅延が発生する可能性があります。最悪の場合、数百クロック サイクルの遅延が発生する可能性があります。例えば

以下を検討してください。

int i; // happens to be 0

if (i > 0) {
   int j = 100 / i;

ブランチが通常取られるとします。これは、分岐が行われないことを認識する前に、割り込み (または Java ではエラー) をトリガーする命令をパイプラインにロードできることを意味します。これにより、正しく巻き戻すのに時間がかかる複雑な状況が発生する可能性があります。

これらは予測ミス分岐と呼ばれます。要するに、ほぼ常に同じように進む分​​岐は高速であり、突然変化する分岐や非常にランダムな分岐 (たとえば、並べ替えやツリー データ構造) は遅くなります。

于 2012-08-28T08:37:26.240 に答える
1

Int は 32 ビット システムの方が速く、 long は 64 ビット システムの方が速いかもしれません。私はそれについて気にする必要がありますか?いいえ、要件に基づいてコーディングするシステム構成をコーディングする必要はありません。マイクロ最適化は機能せず、前例のない問題が発生する可能性があります。

于 2012-08-28T08:33:01.817 に答える
0

小さな Integer オブジェクトは、Java が特定のオブジェクトを扱うため、高速になる可能性があります。

-128 && i <= 127 のすべての整数値は、Integer の内部クラスである IntegerCache に格納されます。

于 2012-08-28T08:36:19.657 に答える