C ++の前後のインクリメント/デクリメント演算子は、ループで同じパフォーマンスを持ちますか? [複製]
質問
次の2つの例を検討してください。
class ClassOne
{
//class definition is here
};
std::vector< ClassOne > myListOfObjects;
std::vector< ClassOne >::const_iterator iter = myListOfObjects.begin();
Example 1:
for( ; iter < myListOfObjects.end(); **++iter**)
{
//some operations
}
OR
Example 2:
for( ; iter < myListOfObjects.end(); **iter++**)
{
//some operations
}
どちらが速いですか?ループのコンテキストでの++ iterまたはiter ++。
閉鎖の理由:
ブライアンの投稿からコピー(質問をより簡潔にするため)。
解決
この回答、preより速いです。これらは、プリミティブ(int、charなど)を扱う場合にのみ同じです。この場合、オーバーロードされた演算子を呼び出しています。
他のヒント
いいえ、同じパフォーマンスはありません:
- Postincrementはコピーを作成してから増分し、コピーを返します
- Preincrementは増分してから元の値を返します
そのため(intのような単純なものを処理している場合を除き)、プリインクリメントは高速です。
状況によります。単純なコンパイラーでは、プリインクリメントが高速になります。擬似コードでは、それぞれの機能は次のとおりです。
preincrement() {
val = val + 1;
return val;
}
postincrement() {
tmp = val; // take a temporary copy of the old value
val = val + 1;
return tmp;
}
実際には、コンパイラは、ポストインクリメントを回避できる場合、ポストインクリメントをプリインクリメントに変換することがよくあります 。ただし、複合型の場合、それができない場合があります。一般的なルールとして、可能な限りpreincrementを使用し、その操作の特定のセマンティクスが必要な場合にのみpostincrmenetを使用します。
非プリミティブ型を扱う場合: ++ iterは常により効率的です。
++ iterの方が効率的である理由は、戻り値を取得するためにそれぞれが必要とする作業にあります。戻り値が実際に使用されるかどうかは関係ありません。
違い:
-
++ iterは自分自身への参照を返すため、一時的なコピーは必要ありません。 (インクリメント、独自の値への参照を返す)
-
iter ++は変数の一時コピーを返します(古い値でtemp varを作成し、増分し、temp varを返します)
_Myt _Tmp = *this; ++*this; return (_Tmp);
これらの同様の質問のいずれかを試すこともできます。こちらまたはこちらまたはこちらまたはこちら。ただし、イテレータには適用されないため、まったく同じではありません。
私は彼らがマシンコードで同じことを、異なる順序で減らすことにほぼ肯定的です。同じだと思いますが、簡単なテストアプリを作成して確認することをお勧めします。
一般に、ポストインクリメントの特別な必要がない限り、プレインクリメントはより良いです。
ただし、これはコンパイラ固有のものです。最新のコンパイラのほとんどは、プレフィックス表記のopsを少なくします。クラスメソッドのオーバーロードでは、クラスの実装方法に依存するため、これは常に最適化されるとは限りません。