Sehr ähnlich wie diese Frage , außer dass stattdessen vector<int>
Ich habe vector<struct myType>
.
Wenn ich für jedes Element im Vektor myType.myVar
zurücksetzen möchte (oder auf einen Wert setzen möchte), was ist die effizienteste Methode?
Im Moment durchlaufe ich:
%Vor%Aber da Vektoren garantiert zusammenhängend gespeichert werden, gibt es sicher einen besseren Weg?
Das Zurücksetzen muss jedes Element des Vektors durchlaufen, so dass es mindestens O (n) -Komplexität braucht. Ihr aktueller Algorithmus benötigt O (n).
In diesem speziellen Fall können Sie operator[]
anstelle von at
verwenden (das könnte eine Ausnahme auslösen). Aber ich bezweifle, dass das der Flaschenhals Ihrer Anwendung ist.
In diesem Sinne sollten Sie wahrscheinlich std::fill
verwenden:
Aber wenn Sie nicht auf Byte-Ebene gehen und einen Teil des Speichers auf 0
setzen wollen, was Ihnen nicht nur Kopfzerbrechen bereitet, sondern in den meisten Fällen auch die Portabilität verliert, gibt es hier nichts zu verbessern.
Anstelle des untenstehenden Codes
%Vor%mache es wie folgt:
%Vor%Da die "at" -Methode intern prüft, ob der Index außerhalb des gültigen Bereichs liegt oder nicht. Da der Schleifenindex jedoch berücksichtigt wird (myVec.size ()), können Sie die zusätzliche Überprüfung vermeiden. Ansonsten ist dies der schnellste Weg, es zu tun.
BEARBEITEN
Zusätzlich können wir die Größe () des Vektors vor dem Ausführen der for-Schleife speichern. Dies würde sicherstellen, dass es keinen weiteren Aufruf der Methode size () innerhalb der for-Schleife gibt.
Einer der schnellsten Wege wäre das loop unwinding und das Geschwindigkeitslimit konventioneller for
-Schleifen, das zu großen Geldverschüttungen führt. In Ihrem Fall, da es sich um eine Laufzeit handelt, gibt es keine Möglichkeit, die Template-Metaprogrammierung anzuwenden, sodass eine Abwandlung des guten alten Duff-Geräts den Trick machen würde
Hier wähle ich einen 8-Block-Abwickelvorgang, um den Wert (sagen wir mal) b einer myStruct
-Struktur zurückzusetzen. Die Blockgröße kann optimiert werden und Schleifen werden effektiv abgerollt. Denken Sie daran, dies ist die zugrunde liegende Technik in memcpy
und eine der Optimierungen (Schleifen-Abrollung im Allgemeinen) wird ein Compiler versuchen (eigentlich sind sie ziemlich gut darin, also können wir sie genauso gut ihre Arbeit machen lassen).
Hüten Sie sich davor, viel Zeit damit zu verbringen, über Optimierungsdetails nachzudenken, die der Compiler nur für Sie erledigen wird.
Hier sind vier Implementierungen dessen, was ich unter dem OP verstehe, zusammen mit dem Code, der mit gcc 4.8 mit --std=c++11 -O3 -S
Erklärungen:
%Vor%Explizite Schleifenimplementierungen, grob aus Antworten und Kommentaren, die dem OP zur Verfügung gestellt wurden. Beide produzierten neben Etiketten einen identischen Maschinencode.
%Vor% Zwei andere Versionen, eine mit std::for_each
und die andere mit dem Bereich for
Syntax. Hier gibt es einen subtilen Unterschied im Code für die beiden Versionen (außer den Labels):
Tags und Links c++ performance vector