6 Stimmen

c++ für Schleife temporäre Variable verwenden

Welche der folgenden Möglichkeiten ist besser und warum? (Speziell für C++)

a.

int i(0), iMax(vec.length());//vec is a container, say std::vector
for(;i < iMax; ++i)
{
  //loop body
}

b.

for( int i(0);i < vec.length(); ++i)
{
  //loop body
}

Ich habe Ratschläge für (a) wegen des Aufrufs der Längenfunktion gesehen. Das beunruhigt mich. Optimiert nicht jeder moderne Compiler (b) so, dass es ähnlich wie (a) ist?

1 Stimmen

Sollte wahrscheinlich in vec.size() geändert werden

1 Stimmen

Sehr interessante Antworten. Erstaunlich, wie einfache Fragen auf Stack Overflow eine Quelle für große Bildung sein können.

1 Stimmen

@Amod: Bitte beachten Sie die Antwort von Andrew Shepherd: die beiden von Ihnen angegebenen Codeblöcke sind NICHT gleichwertig!

0voto

Alex Martelli Punkte 805329

Es ist sehr schwer für einen Compiler, die vec.length() Aufruf in der Gewissheit, dass er konstant ist, es sei denn, er wird inlined (was hoffentlich oft der Fall sein wird!). Aber zumindest i sollte unbedingt im zweiten Stil "b" deklariert werden, auch wenn die length Anruf muss "manuell" aus der Schleife geholt werden!

0 Stimmen

Das ist für Compiler sehr schwierig, aber der Branch Predictor wird sich darum kümmern.

0voto

stefanB Punkte 72857

Dieser ist vorzuziehen:

typedef vector<int> container; // not really required,
                               // you could just use vector<int> in for loop

for (container::const_iterator i = v.begin(); i != v.end(); ++i)
{
    // do something with (*i)
}
  • Ich kann sofort erkennen, dass der Vektor nicht aktualisiert wird
  • jeder kann sagen, was passiert ist hier
  • Ich weiß, wie viele Schleifen
  • v.end() gibt den Zeiger eins hinter der letzten Element zurück, so dass es keinen Overhead der Überprüfung der Größe
  • leicht zu aktualisieren für verschiedene Container oder Werttypen

0voto

(b) die Funktion nicht jedes Mal berechnet/aufruft.

-- Beginn des Auszugs ----

Schleifeninvariante Code-Bewegung: Der GCC umfasst die Schleifeninvarianz als Teil seiner Schleifenoptimierung sowie in seinem Durchgang zur Beseitigung von Teilredundanzen. Durch diese Optimierung werden Anweisungen aus Schleifen entfernt, die einen Wert berechnen, der sich während der gesamten Lebensdauer einer Schleife nicht ändert.

--- Auszug beenden --

Weitere Optimierungen für gcc:

https://www.in.redhat.com/software/gnupro/technical/gnupro_gcc.php3

0voto

Roddy Punkte 64661

Warum nicht das Problem ganz umgehen mit BOOST_FOREACH

#include <boost/foreach.hpp>

std::vector<double> vec;

//...

BOOST_FOREACH( double &d, vec)
{
    std::cout << d;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X