15

Exact Duplicate : C++ で i++ と ++i の間にパフォーマンスの違いはありますか?
正確な複製:ループ内の i++ と ++i の違い?


i++ と ++i のどちらがより効率的ですか?

私はこれを Java と C/C++ でしか使用していませんが、これが実装されているすべての言語を本当に求めています。

大学では教授に ++i の方が効率的であることを教えてもらいましたが、それから数年が経ちました。スタック オーバーフロー コミュニティから意見を求めたいと思います。

4

20 に答える 20

49

i++ :

  • i の一時コピーを作成する
  • インクリメント i
  • 一時コピーを返す

++私:

  • インクリメント i
  • 私を返す

最適化をオンにすると、結果のアセンブリが同じになる可能性は十分にありますが、++i の方が効率的です。

edit : C++ では、 i は前置および後置 ++ 演算子をサポートするオブジェクトであれば何でもよいことに注意してください。複雑なオブジェクトの場合、一時コピーのコストは無視できません。

于 2009-02-18T15:46:18.143 に答える
37

最適化の可能性については、他の場所を探します。

于 2009-02-18T15:45:35.977 に答える
7

効率は気にするべきではありません。それは意味です。独立していない限り、この 2 つは同じではありません。1つは値の事前使用を操作し、もう 1 つはポストを操作します。

int i; 私は= 1; cout << i++; // 1 を返します

int i; 私は= 1; cout << ++i; // 2 を返します

意味が重要でない場合、ほとんどのコンパイラは ++i と i++ の両方を (たとえば for ループで) 同じマシン/VM コードに変換します。

于 2009-02-18T15:46:23.570 に答える
5

最新のコンパイラでは問題ありません。

int v = i++;  

と同じです

int v = i;
i = i + 1;

最新のコンパイラは、vが未使用であり、計算するコードvが純粋 (副作用なし) であることを検出します。v次に、割り当てコードを削除し、これを生成します

i = i + 1;
于 2009-02-18T15:43:35.543 に答える
3

それは問題である!特に、カスタム イテレータ プロトコルを使用する C++ ランドにいる場合は...

++i // the prefered way, unless..
auto j = i++ // this is what you need

必要なコピーのオーバーヘッドを避けるために接頭辞表記を使用する必要がありますが、それは反復子にのみ適用され、組み込みのネイティブ型には適用されません。それらは関係なく 1 つの命令にすぎません。

于 2009-02-18T15:45:19.020 に答える
2

++i は、operator++ の非自明な実装ではより効率的である可能性がありますが、そのシナリオでも、コンパイラーは中間一時を最適化して除去できる場合があります。

于 2009-02-18T15:46:36.427 に答える
2

C++ では、変数をいつ更新するかによって、さまざまな用途があると思います。

効率は、どちらを使用するかを決定するものではありませんが、どちらの方法でも同じ効率になると思います。

于 2009-02-18T15:44:25.090 に答える
2

++i は、何かを格納するための一時変数を必要としません。次のように考えてください。

++i

int preIncrement(int i)
{
    i = i + 1;
    return i;
}

i++

int i = 5; // as an example
int postIncrement(_i)
{
    int temp = _i;
    i = _i + 1;
    return temp;
}

見る?ポストインクリメントには一時変数が必要です。コンパイラがすべてを整理しないと仮定すると、ほぼ確実に整理されます。

もちろん、より重要なのはプログラム ロジックです。これについて心配しすぎると、マイクロ最適化シアターの悲しい悲劇に遭遇するリスクがあります... :)

于 2009-02-18T15:49:53.110 に答える
0

一般に、C ++では、接頭辞はオブジェクトに直接適用されますが、接尾辞は増分されたオブジェクトの追加の構築を必要とします。(またはそう私は読んだ。)

私の知識が限られているため、コンパイラがどのように処理するかを証明することはできませんが、それを処理することは重要なポイントになります。

于 2009-02-18T15:54:02.460 に答える
0

++ii++を格納iし、インクリメントしてから、格納された の値を返す必要があるため、高速ですi++i単純にインクリメントiしてから返します。

// ++i
i += 1;
return i;

// i++
temp = i;
i += 1;
return temp;
于 2009-02-18T15:47:29.607 に答える
0

スタンドアロンの「i++;」または「++i;」同等に効率的なコードを生成する必要があります。「副作用」が作用する式で使用している場合、違いが生じます。

そうは言っても、「世界中が Vax である」時代があり、コンパイラが最悪だったので、"for (i = 0; i < N; + +i)」タイプの設定。

于 2009-02-18T15:47:49.310 に答える
0

このスタック オーバーフローの質問には素晴らしい答えがあります。Is there a performance difference between i++ and ++i in C?

ニーズに合った方を使用する必要があることを付け加えておきます。最も時間が重要なアプリケーションを除いて、これは重要ではありません。アカデミックな観点からも、必要なものを表現するコードを書いて、最後に最適化したほうがよいでしょう。

于 2009-02-18T15:48:34.457 に答える
0

私が何かを見逃していない限り、それらは同じ効率を持つはずです。どちらも単一の追加命令になります。add 命令がどこで発生するかだけの問題です: コード行の最初か最後か。

于 2009-02-18T15:44:43.793 に答える
0

++i は、最適化なしの x86 アセンブリで i++ よりもプロセッサ命令が 1 つ少なくて済みます。

于 2009-02-18T15:45:46.833 に答える
0

違いはありません。最も理にかなった構造を使用してください。

アプリケーションの実行速度が遅い場合は、整数インクリメント操作の速度の違いが原因ではないことを保証できます。もしそうなら、それはコンパイラの重大なバグです。アプリケーションの速度の問題は、アルゴリズムの非効率性、I/O の待機などです。

あなたが持っていない問題について心配する必要はありません。時期尚早の最適化は諸悪の根源です

于 2009-02-18T15:46:30.233 に答える
0

一般に、i++ と入力する方が簡単であるため、生産時間の点でより効率的です。

ただし、iがネイティブ データ型 (int、double など) の場合、違いはありません。

そして、それが次のようなユーザー定義型であるかどうかは実装に依存します

class Type
{
    Type& operator ++(){}
    const Type& operator ++(int i){}
};  

T i;
于 2009-02-18T15:49:28.290 に答える
0

正解も不正解もありません。

依存するため:

  1. コンパイラによる実装方法。

  2. システムが実行されている CPU。

  3. iバイトまたはiダブルワードの場合

于 2009-02-18T15:49:43.720 に答える
0

コンテキストによって異なります。たとえば、次のようになります。

x = i++

この場合、'x' は 'i' と等しくなり、その後で初めて 'i' が 1 増加します。

x = ++i

この場合、'i' が 1 増加し、'x' の新しい値が 'x' に割り当てられます。

for ループの場合、パフォーマンス以外に明らかな違いはほとんどありません (++i の方が高速です)。

于 2009-02-18T15:50:19.600 に答える
0

一般に、i++ よりも ++i を使用する方が効率的です。これの単純な理由は、++i が以下とまったく同じだからです。

私は += 1;

x86の場合、これは単一の命令です(そしておそらく他の広く使用されているアーキテクチャのほとんど)。ただし、i++ は次の値に等しい

tmp = 私; 私は += 1;

これは、'i' の古い値が i++ の評価対象となるためです。そして明らかに、単に i += 1; よりも多くの作業が必要です。

しかし、上で述べたように、これは未使用の操作を最適化するため、十分に賢いコンパイラではほとんど影響を与えません。多くのインタープリター型言語 (例: PHP) では、++i の速度がわずかに向上する可能性があります。しかし、この増加はごくわずかです。

于 2009-02-18T15:50:50.910 に答える
-1

コンパイラ/インタープリタの実装に依存するため、これに正確に答えるのは困難です。

しかし、一般的に言えば、i++ を次の命令に大まかに拡張すると言えます。

COPY i to tmp
INCREMENT tmp
SAVE tmp as i

++i はおおよそ次のように拡張されます。

LOAD i
INCREMENT i

++i は i++ よりも高速であるとは言えません。言語の実装は非常にスマートであり、i++ の一時的な値にアクセスしないことがわかっている場合にこれらの命令を最適化できるためです。これは通常、たとえば for ループで発生します。したがって、多くの場合、それはまったく同じです。

この種のマイクロ最適化を試みている場合は、いずれかを選択する前にプロファイリング/測定することをお勧めします。

于 2009-02-18T15:52:50.530 に答える