Vermeidung von if-Anweisungen innerhalb einer for-Schleife?
Habe ich eine Klasse namens Writer
hat eine Funktion writeVector
etwa so:
void Drawer::writeVector(vector<T> vec, bool index=true)
{
for (unsigned int i = 0; i < vec.size(); i++) {
if (index) {
cout << i << "\t";
}
cout << vec[i] << "\n";
}
}
Ich versuche, nicht zu haben, einen doppelten code, während immer noch sorgen um die performance.
In der Funktion mache ich das if (index)
überprüfen Sie auf jeder Runde mit meiner for
-Schleife, obwohl das Ergebnis immer das gleiche.
Dies ist gegen die "Gedanken über die Leistung".
Konnte ich problemlos vermeiden, indem Sie die Prüfung außerhalb meiner for
-Schleife.
Jedoch, ich erhalten jede Menge doppelten code:
void Drawer::writeVector(...)
{
if (index) {
for (...) {
cout << i << "\t" << vec[i] << "\n";
}
}
else {
for (...) {
cout << vec[i] << "\n";
}
}
}
Also sind diese beiden "schlechten" Lösungen für mich.
Worüber ich nachgedacht habe, ist zwei private Funktionen, einer von Ihnen outs der index und ruft dann die anderen.
Die andere nur outs Wert.
Allerdings kann ich nicht herausfinden, wie es mit meinem Programm, ich würde noch die if
überprüfen, um zu sehen, was man nennen...
Nach das problem, Polymorphismus scheint wie eine richtige Lösung.
Aber ich kann nicht sehen, wie soll ich es hier.
Was wäre die bevorzugte Art und Weise zu lösen diese Art von problem?
Dies ist nicht ein echtes Programm, ich bin nur daran interessiert zu lernen, wie man diese Art von problem sollte gelöst werden.
InformationsquelleAutor der Frage Skamah One | 2013-06-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Pass in den Körper der Schleife als Funktor. Es wird inlined zur compile-Zeit, keine Leistungseinbußen.
Die Idee der übergabe in dem, was variiert, ist allgegenwärtig in der C++ Standard-Bibliothek. Es heißt Strategie-Muster.
Wenn Sie erlaubt sind zu verwenden, C++11, können Sie etwas wie das hier tun:
Dieser code ist nicht perfekt, aber Sie bekommen die Idee.
In alten C++98 sieht es so aus:
Wieder, der code ist bei weitem nicht perfekt, aber es gibt Sie, die Idee.
InformationsquelleAutor der Antwort Ali
Wenn dies tatsächlich der Fall ist, wird der Zweig-predictor-haben kein problem in der Vorhersage der (Konstante) Ergebnis. Als solche, diese wird nur dazu führen, dass eine milde Aufwand für mispredictions in den ersten paar Iterationen. Es ist nichts zu befürchten in Bezug auf Leistung
In diesem Fall plädiere ich für die Beibehaltung der test innerhalb der Schleife für Klarheit.
InformationsquelleAutor der Antwort Marc Claesen
Erweitern auf Ali ' s Antwort, die absolut korrekt sind, aber noch Duplikate code (Teil der Schleife, das ist leider kaum vermeidbar, wenn der Strategie-Muster)...
Gewährt in diesem speziellen Fall die code-Duplizierung ist nicht viel, aber es gibt einen Weg, um es zu verringern, noch mehr, die kommt in handliches wenn die Funktion Körper, die größer ist, als nur ein paar Anweisungen.
Der Schlüssel ist die Verwendung der compiler die Leistungsfähigkeit constant folding /dead code elimination. Wir können tun, dass durch die manuelle Zuordnung der Laufzeit-dem Wert des
index
zu einem compile-Zeit-Wert (einfach zu tun, wenn es gibt nur eine begrenzte Anzahl von Fällen-zwei in diesem Fall) und eine non-type template argument, das ist bekannt, zur compile-Zeit:Diese Weise landen wir mit kompiliertem code, der äquivalent ist zu deinem zweiten code-Beispiel (äußere
if
/innenfor
), jedoch ohne Duplizierung der code selbst. Nun können wir die template-version vonwriteVector
so kompliziert, wie wir wollen, es wird immer ein Stück code zu pflegen.Beachten Sie, wie die version der Vorlage (das dauert ein compile-time-Konstanten in der form einer non-type template argument) und die nicht-template-version (das dauert eine Laufzeit-variable als Funktions-argument) sind überlastet. Dies ermöglicht Ihnen, wählen Sie die entsprechende version je nach Ihren Bedürfnissen, mit einem ziemlich ähnlichen, leicht zu merken-syntax in beiden Fällen:
InformationsquelleAutor der Antwort syam