2015-10-19 16 views
5

Se ho chiamata di funzione a condizione del ciclo come questo:Chiamata di funzione per condizione loop?

for (auto it = s.begin(); it != s.end(), ++it) {} 

si chiama ad ogni iterazione? Mi aspetto di sì. Il compilatore consente di ottimizzarlo? I compilatori attuali sono abbastanza intelligenti da farlo? O sto meglio usando qualcosa come il seguente:

for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {} 

?

+0

Poiché si utilizza C++ 11, è consigliabile utilizzare il ciclo per ciclo basato su intervalli che evita questo problema. –

+0

@NeilKirk non utilizzabile nel mio caso, in realtà ho bisogno che l'iteratore faccia cose divertenti. – Paladin

+1

Personalmente scrivo i miei loop usando il tuo secondo approccio, quindi non devo preoccuparmene. Non so quanto sia importante o meno nella pratica. –

risposta

4

Sì, il programma deve chiamare la seconda espressione it != s.end() ad ogni iterazione. Penso che il compilatore possa ottimizzarlo in certe situazioni.

In ogni caso, non eseguire il lavoro del compilatore. Se può essere ottimizzato, c'è una grande possibilità che il compilatore lo faccia già, e comunque questa chiamata non ha un impatto significativo sulle prestazioni.

Se il caso lo permette, è necessario utilizzare una gamma basata ciclo for:

for (auto& i : s) { 
    // instructions 
} 

In questo modo, il compilatore hanno anche maggiori opportunità di ottimizzare il codice ed è più facile da leggere.

Se vuoi qualche esempio su quanto il compilatore può ottimizzare, guarda questo! http://ridiculousfish.com/blog/posts/will-it-optimize.html

+0

Normalmente lo userò, ma in realtà ho bisogno di manipolare un po 'l'iteratore, quindi il classico ciclo foreach non funzionerà per me – Paladin

+0

Ah, allora usa il classico ciclo for. Ma ancora, il compilatore è molto intelligente. In questo caso non è necessario complicare il codice. –

+0

Ho modificato la mia risposta per essere più generica e ho appena aggiunto un link a un grande articolo. –

6

In

for (auto it = s.begin(); it != s.end(), ++it) 

s.begin() viene chiamato solo una volta.
s.end() e operator++() (per ++it) vengono chiamati in ogni iterazione del ciclo.

Il compilatore consente di ottimizzarlo?

Il compilatore può ottimizzare la chiamata a s.end() a seconda del compilatore, dell'implementazione e del livello di ottimizzazione. Sarò sorpreso se riuscirà a ottimizzare la chiamata operator++().

I compilatori correnti sono abbastanza intelligenti da farlo?

Impossibile rispondere.

O sto meglio usando qualcosa come segue:

for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {} 

Non farà male. Tuttavia, può essere un problema se s viene modificato nel ciclo. Se s non viene modificato nel ciclo, ti consigliamo di utilizzare questo approccio.

1

Sì, è formalmente chiamato ad ogni iterazione. E sì, i compilatori attuali probabilmente incoraggeranno la funzione e vedranno che s.end() restituisce lo stesso valore (puntatore?) Ogni volta.

Non è necessario complicare il codice, a meno che la profilazione non indichi che si tratta di un collo di bottiglia nel programma (estremamente improbabile).

Problemi correlati