16

プログラミングの授業で、教授はx++とについて教えてくれ++xました。x は整数です。

彼は、シナリオでは、 または のいずれかを配置することができx++++xより++x効率的であると述べました (少しずつではありますが、それでも理論的にはより効率的です)。

しかし、私は理由を忘れました。誰でも知っていますか?これはJavaでした。

4

3 に答える 3

25

Javaでは効率的ではありません。インクリメント/デクリメント演算子をオーバーロードできる言語ではより効率的ですが、それ以外のパフォーマンスはまったく同じです。

x++との違いは++x、 インクリメントされる前x++の値を返し、インクリメントされた後の値を返すことです。コード生成に関しては、少なくともどちらかを互換的に使用できる場合は、どちらもまったく同じ数の命令を補います (互換的に使用できない場合は、どちらが高速かを気にする必要はありません。必要なものを選択してください)。唯一の違いは、インクリメント命令が配置される場所です。x++xx

C++ では、クラスは前置 ( ) 演算子++xと後置 ( x++) 演算子の両方をオーバーロードできます。それらをオーバーロードする型を扱う場合、ほとんど例外なく前置演算子を使用する方が高速です。これは、後置演算子のセマンティクスにより、使用しない場合でもインクリメント前のオブジェクトのコピーが返されるためです。前置演算子は、変更されたオブジェクトへの参照を単純に返すことができます (そして、C++ 開発者がコピーではなく参照を返すことを好むことを神は知っています)。これは、C++よりも優れていると考える理由になる可能性があります。C++を使用する習慣を 身につければ、C++ に切り替えた場合のわずかなパフォーマンスの問題を回避できます。ただし、Java のみのコンテキストでは、どちらも完全に同等です。++xx++++x

上記のコメントのpstと同じように、私はx++orの戻り値を決して使用し++xません。

于 2012-09-12T22:02:23.877 に答える
16

好奇心から、生成されたバイトコードを確認できます。

このプログラム:

public static void main(String args[]) {
    int i = 1; //bytecode 0, 1
    i++; //bytecode 2
    ++i; //bytecode 5
    int a = ++i; //bytecode 8, 11, 12
    int b = i++; //bytecode 13, 14, 17
}

次のバイトコードを生成します。

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: iinc          1, 1
       5: iinc          1, 1
       8: iinc          1, 1
      11: iload_1
      12: istore_2
      13: iload_1
      14: iinc          1, 1
      17: istore_3
      18: return

したがって、修正前と修正後の演算子は、バイトコードの観点からは厳密に同一であることがわかります(操作の順序は別として)。

JITがコードのその部分をコンパイルする場合、すべての賭けは無効になります。たとえば、上記のコードは、副作用がないため、そのままコンパイルできます。

于 2012-09-12T22:46:39.100 に答える
4

実のところ、PDP-11やおそらく VAXのC*x++よりも高速でした。これは、単一の命令 (自動インクリメント レジスタの遅延) にコンパイルされたためです。同様に よりも高速でした。逆参照なしでどちらの形式を使用しても、コンパイラがその命令を生成した場合、逆参照が発生したままになるため、無駄な命令が生成された場合にのみ高速になります。*++x *--x*x--

そんな日々はとうの昔に過ぎ去りました。

于 2012-09-12T23:29:21.587 に答える