2013-06-10 9 views
40

対、私はそうのようないくつかのコンテナを反復処理することができますC++ 11の範囲ベースのforループ効率 "のconstオート&i" が "自動I" C++ 11では

for(auto i : vec){ 
    std::cout << i << std::endl; 
} 

しかし、私がいることを知っていますこの不 - 不、私は唯一の印刷にvec値を必要とするので、 - (EDIT:の各要素)のコピーになりvecを、ので、代わりに私が行うことができます:

for(auto &i : vec){ 
    std::cout << i << std::endl; 
} 

は、しかし、私はvecの値が変更されていないとのconst - 正しさを遵守んことを確認するので、私は行うことができます。

for(const auto &i : vec){ 
    std::cout << i << std::endl; 
} 

だから私の質問は:私だけでに必要がある場合(EDIT:の各要素)の余分なコピーを持たないために最後のループ(const auto &i)が常に好ましいとは思わないでしょうvec

私はこの中でこの変更を検討している私が開発しているプログラムを持っています。それは効率が重要であるからです(私が最初の場所でC++を使用している理由)。

+1

はい、引数への読み取りアクセスが必要な場合は、不要なコピーを避けるためには 'auto const&'を使用する必要があります。 – 0x499602D2

+2

"const"キーワードはあなたのコードをもっと速くしません... – Tim

+4

'for(auto i:vec)'は 'vec'全体の余分なコピーを作成せず、' vec'の各要素をコピーします。 「i」にする。 – Casey

答えて

54

はい。引数を読んだだけの場合は、同じ理由でパラメータconst&を作成します。

T  // I'm copying this 
T&  // I'm modifying this 
const T& // I'm reading this 

これは「デフォルト」です。 Tが基本タイプ(内蔵)の場合、コピーはエイリアシングよりも安価であるため、一般的にはconst T(参照なし)に戻って読み込みます。


私は効率が

  1. それに重要であることから、私は全体でこの変更を行う検討しているここで開発していたプログラムを持っている盲目の抜本的な変更を加えないでください。 。速くて壊れたプログラムよりも働くプログラムが優れています。
  2. ループを反復処理しても、おそらく大きな違いはありません。あなたは理由のためにループしているのですか?あなたのループのボディは、はるかに可能性が高いです。
  3. 効率が重要である場合は、実際遅いのではなく、遅いかもしれない部分を推測である、あなたのプログラムの部分を見つけるためにプロファイラを使用します。なぜあなたの推測が間違っているのか#2を見てください。
+0

"コピーはエイリアシングよりも安価です"というのは、ほとんどの基本的な型だけですが、移動セマンティクスはOPの状況では使用できませんでした。また、Tは任意の型でよいため、参照は正しい選択です。 – Tim

+1

"*"コピーはエイリアシングよりも安い "ほとんどの基本的な型だけ*"なぜその文の最初の半分がそれが基本型に適用されると言うことに専念しているのですか?明らかに型がわからない場合は、一般的なケースを使用します。 – GManNickG

+0

すみません、私はそれを読んだことがあります。 – Tim

0

ベクターに文字列が含まれているとします。長い文字列。 5000の長い文字列。それらを不必要にコピーすると、非常に効率の悪いforループが作成されます。

あなたのコードがあなたの意図に従っていることを確認してください。ループの内部にコピーが必要ない場合は、コピーを作成しないでください。

上記のように参照番号&を使用するか、イテレータを使用してください。

関連する問題