Mit Blick auf die Assembly-Ausgabe rollt gcc diese Schleife tatsächlich in die Verwendung der mmx-Register ab, um jeweils 16 Byte zu sichern, bis sie sich dem Ende nähert. Ich würde sagen, das geht ziemlich schnell. Die Memset-Version springt zu Memset, was meiner Meinung nach ungefähr genauso schnell ist. Ich würde deine Methode anwenden.
Omnifarious
Das Springen zum Memset ist jedoch eine einzelne Anweisung, sodass die Verwendung zu einer kleineren Binärgröße führt.
Alexander Shishenko
2
Dies ist nicht genau das, wonach OP gefragt hat, aber die einfache Neuzuweisung Ihres Vektors zu einem neuen Vektor derselben Größe ( v = std::vector<int>(vec_size,0)) scheint etwas schneller zu sein als fillauf meinem Computer
Yibo Yang
1
Dies ist die idiomatischste Art, dies zu tun, idiomatischer als die Verwendung assign.
alfC
1
Hat die Zuweisung zu einem neuen Vektor eine Heap-Zuordnung? und dann die Zuordnung des vorhandenen Vektors verwerfen? Ich konnte sehen, dass es langsamer war als memset et al.
Conrad Jones
150
Wie immer, wenn Sie nach dem schnellsten fragen: Messen! Verwenden der oben genannten Methoden (auf einem Mac mit Clang):
Verwenden von 100000 Iterationen auf einem Vektor von 10000 Ints.
Edit: Wenn changeing diese Zahlen plausibel die resultierenden Zeiten ändert können Sie etwas Vertrauen (nicht so gut wie die Endmontage Code Inspektion) , dass die künstliche Benchmark nicht optimiert wurde entfernt vollständig. Natürlich ist es am besten, die Leistung unter realen Bedingungen zu beeinträchtigen.
Ende Bearbeiten
+1. Dieser spezielle Benchmark ist nicht schlüssig, aber der Punkt ist absolut richtig. Sie sollten einen Leistungstest der Alternativen schreiben, da diese tatsächlich verwendet werden. Wenn es keinen Leistungsunterschied gibt, verwenden Sie die einfachste Quelle.
Steve Jessop
3
"... nicht schlüssig ..." IMO ist diese Unschlüssigkeit an sich schon ein guter Punkt für Benchmarks. Meistens leistet der Optimierer bereits sehr gute Arbeit für die Art von Situationen, nach denen das OP gefragt hat. Und ich würde Ihren letzten Satz dahingehend ändern, dass er lautet: "Wenn es keinen signifikanten Leistungsunterschied gibt ..."
Wow, wenn Sie Wert auf Geschwindigkeit ohne Optimierungen legen (was plausibel sein kann, wenn Sie im Debug-Modus bereitstellen, was einige Teams tun), fillsieht das schrecklich aus. In diesem Test ist es zwei Größenordnungen langsamer.
Kyle Strand
5
@KyleStrand: Es ist nicht so, dass das Füllen schrecklich ist, es ist eine Vorlage und der Code wird mit -O0 in Ihrer Übersetzungseinheit generiert. Wenn Sie memset verwenden, verwenden Sie den libc-Code, der mit -O3 kompiliert wurde (auch wenn Sie Ihren Code mit -O0 kompilieren). Wenn Sie Wert auf Geschwindigkeit beim Debuggen legen und Vorlagen verwenden, müssen Sie die explizite Vorlageninstanziierung in einer separaten Datei verwenden, die Sie mit -O3
Da der Standard (2003 TC1) garantiert, dass ein std :: vector im Speicher zusammenhängend ist, sollte dies in Ordnung sein. Wenn Ihre c ++ - Bibliothek nicht mit dem 2003 TC1 übereinstimmt, verwenden Sie diese nicht.
Mario
2
@Mario: Ich hätte das nicht gepostet, wenn das nicht wahr wäre und natürlich als bekannt angenommen worden wäre. :) Aber danke.
Entspannen Sie am
1
Ich habe die Baugruppe überprüft. Die ::std::fillMethode erweitert sich zu etwas, das verdammt schnell ist, wenn auch etwas Code-aufgebläht, da alles inline ist. Ich würde es trotzdem benutzen, weil es viel schöner zu lesen ist.
Omnifarious
4
Sie sollten besser hinzufügen, ob der Vektor leer ist, und in diesem Fall nichts tun. Das Berechnen von & buf [0] für einen leeren Vektor kann Zusicherungen im STL-Code erzeugen.
Sergey
4
Versuchen
std::fill
und auch
std::size siz = vec.size();//no memory allocating
vec.resize(0);
vec.resize(siz,0);
Ich hatte die gleiche Frage, aber ziemlich kurz vector<bool>(afaik erlaubt der Standard, sie intern anders zu implementieren als nur ein kontinuierliches Array von booleschen Elementen). Daher wiederholte ich die leicht modifizierten Tests von Fabio Fracassi. Die Ergebnisse sind wie folgt (Zeiten in Sekunden):
-O0 -O3----------------
memset 0.6661.045
fill 19.3571.066iterator67.3681.043
assign 17.9750.530for i 22.6101.004
Also anscheinend für diese Größen vector<bool>::assign()ist schneller. Der für Tests verwendete Code:
Antworten:
quelle
v = std::vector<int>(vec_size,0)
) scheint etwas schneller zu sein alsfill
auf meinem Computerassign
.Wie immer, wenn Sie nach dem schnellsten fragen: Messen! Verwenden der oben genannten Methoden (auf einem Mac mit Clang):
Verwenden von 100000 Iterationen auf einem Vektor von 10000 Ints.
Edit: Wenn changeing diese Zahlen plausibel die resultierenden Zeiten ändert können Sie etwas Vertrauen (nicht so gut wie die Endmontage Code Inspektion) , dass die künstliche Benchmark nicht optimiert wurde entfernt vollständig. Natürlich ist es am besten, die Leistung unter realen Bedingungen zu beeinträchtigen. Ende Bearbeiten
als Referenz den verwendeten Code:
Fazit: verwenden
std::fill
(weil, wie andere gesagt haben, es am idiomatischsten ist)!quelle
assign
ist langsamer, mit Ausnahme kleiner Kapazitäten auflibc++
. CODE coliru / pastefill
sieht das schrecklich aus. In diesem Test ist es zwei Größenordnungen langsamer.Wie wäre es mit der
assign
Mitgliedsfunktion?quelle
Wenn es nur ein Vektor von ganzen Zahlen ist, würde ich zuerst versuchen:
Es ist nicht sehr C ++, daher bin ich sicher, dass jemand den richtigen Weg dafür finden wird. :) :)
quelle
::std::fill
Methode erweitert sich zu etwas, das verdammt schnell ist, wenn auch etwas Code-aufgebläht, da alles inline ist. Ich würde es trotzdem benutzen, weil es viel schöner zu lesen ist.Versuchen
und auch
quelle
Ich hatte die gleiche Frage, aber ziemlich kurz
vector<bool>
(afaik erlaubt der Standard, sie intern anders zu implementieren als nur ein kontinuierliches Array von booleschen Elementen). Daher wiederholte ich die leicht modifizierten Tests von Fabio Fracassi. Die Ergebnisse sind wie folgt (Zeiten in Sekunden):Also anscheinend für diese Größen
vector<bool>::assign()
ist schneller. Der für Tests verwendete Code:Ich habe den GCC 7.2.0-Compiler unter Ubuntu 17.10 verwendet. Die Befehlszeile zum Kompilieren:
quelle