2013-06-10 17 views
40

In C++ 11, posso iterare su alcuni container in questo modo:C++ 11 efficienza per-loop "auto const & i" contro "auto i"

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

Ma so che questo inutilmente - inutilmente, dal momento che ho solo bisogno di stampa i valori della vec - crea una copia del (EDIT: ogni elemento di) vec, così invece ho potuto fare:

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

ma voglio fare in modo che i valori di vec non vengono mai modificati e rispettare const correttezza, così posso fare:

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

Quindi la mia domanda è: Se solo ho bisogno di sguardo al valori di alcuni contenitori, non sarebbe sempre preferibile l'ultimo ciclo (const auto &i) a causa della maggiore efficienza di non avere una copia aggiuntiva di (EDIT: ogni elemento di) vec?

Ho un programma che sto sviluppando in cui sto pensando di apportare questo cambiamento, poiché l'efficienza è fondamentale in esso (il motivo per cui sto usando C++ nel primo posto).

+1

Sì, se è necessario solo l'accesso in lettura a un argomento, è necessario utilizzare 'auto const &' per evitare una copia non necessaria. – 0x499602D2

+2

La parola chiave "const" non sta rendendo il tuo codice più veloce anche se ... – Tim

+4

'for (auto i: vec)' non crea una copia extra dell'intero 'vec', copia ogni _element_ di' vec' in 'i'. – Casey

risposta

54

Sì. Lo stesso motivo per cui leggi sempre un argomento solo il parametro const&.

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

Queste sono le "impostazioni predefinite". Quando T è un tipo fondamentale (incorporato), tuttavia, in genere si torna a const T (nessun riferimento) per la lettura, poiché una copia è più economica di un aliasing.


Ho un programma che sto sviluppando in cui sto pensando di fare questo cambiamento in tutto, dal momento che l'efficienza è fondamentale in esso

  1. Non apportare cambiamenti radicali non vedenti . Un programma di lavoro è meglio di un programma veloce ma rotto.
  2. La modalità di iterazione dei loop probabilmente non farà molta differenza; stai andando in giro per una ragione, non è vero? Il corpo del tuo ciclo sarà molto probabilmente il colpevole.
  3. Se l'efficienza è fondamentale, si desidera utilizzare un profiler per trovare quale parti del programma sono in realtà lento, piuttosto che indovinare parti che potrebbero essere lento. Vedi # 2 per il motivo per cui la tua ipotesi potrebbe essere sbagliata.
+0

"la copia è più economica di un aliasing" solo con i tipi più fondamentali, oltre a spostare la semantica non può essere utilizzata nella situazione dell'OP e dato che T può essere di qualsiasi tipo, un riferimento sarebbe la scelta giusta. – Tim

+1

"*" la copia costa meno dell'aliasing "solo con i tipi più fondamentali *" Per quale motivo la prima parte di questa frase è dedicata a dire che si applica ai tipi fondamentali ...? Ovviamente se non conosci il tipo, usi il caso generale. – GManNickG

+0

Scusami, devo averlo letto. – Tim

0

Immagina se il tuo vettore contiene stringhe. Corde lunghe. 5000 corde lunghe. Copiali inutilmente e finisci con un ciclo di scrittura ben scritto che è terribilmente inefficiente.

Assicurati che il codice segua la tua intenzione. Se non hai bisogno di una copia all'interno del ciclo, non crearne uno.

Utilizzare un riferimento & come suggerito sopra, o iteratori.