どちらが良いですか?
for (auto anItem = aVector.begin(), endVector = aVector.end(); anItem != endVector ; ++anItem )
また
for (auto anItem = aVector.begin(), anItem != aVector.end(); ++anItem )
私はいつも2番目を使用します-より単純なものです。
最初の方が速いと思いますが、std :: vector :: end()の一般的な実装では、ベクトルの最後の要素の後の最初の要素を指す単純なポインターを返すため、2番目のケースではパフォーマンスが向上しません。 end()は常にインライン関数です。現在のend()を次のconst iterator
ように保存すると、パフォーマンスが向上する可能性があります。
const decltype(aVector.end()) endVector = aVector.end();
for (auto anItem = aVector.begin(); anItem != endVector ; ++anItem )
ただし、このループと最初のループは、多くの場合、2番目のループよりも安全性が低くなります。そのため、ほとんどの場合、2番目のループが表示されます。
[アップデート]
パフォーマンスについて話すとき、最初のループが2番目のループよりも有利であるとは思いません。最新のコンパイラは、aVector.end()の結果がループ全体で変化していないことを検出できるため、自由に最適化できます。最初のループの唯一のパフォーマンス上の利点は、aVectorがループ内で変更された場合ですが、これにより誤った動作が発生します。
したがって、この質問をどの側から見ても、2番目のループの方が常に優れています。
[UPDATE2]
確認するだけです。私はこのような2つの関数を書きました:
int test1(std::vector<int>& a)
{
int retVal = 0;
for (std::vector<int>::iterator it = a.begin(), aend = a.end(); it != aend; ++it)
{
retVal += *it;
}
return retVal;
}
int test2(std::vector<int>& a)
{
int retVal = 0;
for (std::vector<int>::iterator it = a.begin(); it != a.end(); ++it)
{
retVal += *it;
}
return retVal;
}
そして、それらをアセンブラにコンパイルしましたg++ -O3 -S
。私のコンピューター/コンパイラーのアセンブラー・コードに違いはありませんが、これは、すべての場合に違いがないという意味ではありません。
2番目の方が優れています。これは、すべての(はい、100%)プログラマーがそれを使用しているためです。(反復中に何も消去していないと仮定すると、その場合、for
ループは最良の選択ではありません)