Zählvariable, via Prefix o. Postfix erhöhen ?
-
10 Messungen über 200 Mio. Schleifendurchläufe ergeben:
Postfix: 0.376376 s
Prefix: 0.381945 sNimmt sich also so gut wie nichts.
Die Schleifen sehen so aus:
for( int j = 0; j < 200000000; j++ ) { int a = j++; }bzw.
for( int k = 0; k < 200000000; ++k ) { int a = ++k; }Debug Build mit MS VS 2008 Express (ohne Optimierungen).
Im Release Build werden die Schleifen wohl komplett rausoptimiert.
-
Ich wollt eben mal wissen wie das sich mit Iteratoren auswirkt:
#include <iostream> #include <ctime> #include <vector> int main() { clock_t start,finish; std::vector<int> largevector(100000, 5); std::vector<int>::iterator iter; int i; start = clock(); for (iter = largevector.begin(); iter != largevector.end(); iter++) // postfix i = *iter; finish = clock(); std::cout << "postfix: " << (double(finish)-double(start))/CLOCKS_PER_SEC << std::endl; start = clock(); for (iter = largevector.begin(); iter != largevector.end(); ++iter) //prefix i = *iter; finish = clock(); std::cout << "prefix: " << (double(finish)-double(start))/CLOCKS_PER_SEC << std::endl; std::cin >> i; return 0; }Ergebnis auf meinem Schlepptop:
postfix: 0.391
prefix: 0.093Fazit für mich: Ab jetzt nur noch prefix (hab bisher auch - ohne nachzudenken - fast immer postfix benutzt
)Wie groß die Zeitersparnis im Einzelfall ist hängt natürlich dann davon ab wie aufwändig der copy-constructor ist. Bei einem deep copy von arrays oder so kann das heftigst werden!
-
Ist das auch im Release kompiliert? - Kann mir schwer vorstellen, dass der Unterschied so gross wird.
Man kann antürlich mal prinzipiell Prefix benutzen und nur Postfix, wenn man es wirklich braucht. Mache ich auch so.
-
ups..hast recht - war im debug
Um im release was zu sehen musste ich folgende Zeile ändern (sonst kam als Zeit '0' raus)
for (iter = largevector.begin(); iter != largevector.end(); iter++) // postfix i=*iter;in
for (iter = largevector.begin(); iter != largevector.end(); iter++) // postfix for (iter2 = largevector.begin(); iter2 != largevector.end(); iter2++) i=*iter;(und entsprechend natürlich auch für prefix).
Ergebnis:
postfix: 25.765
prefix: 24.625Scheint als ob der Copy-operator von STL-Iteratoren recht effizient ist.
-
Das scheint mir schon eher realistisch. Und dieser Unterschied ist eigentlich zu vernachlässigen.
-
Also ich finde fast 5% Performanceunterschied nicht zu verachten. Besonders wenn man an zeitkritischen Applikationen arbeitet.
-
antialias schrieb:
Also ich finde fast 5% Performanceunterschied nicht zu verachten. Besonders wenn man an zeitkritischen Applikationen arbeitet.
Da hast du schon recht, aber überleg mal wie realistisch dieses extrem Beispiel ist, wo das Programm nichts anderes macht, als jede Menge Zuweisungen.
In keinem realistischen Programm wird die Performance von solch einfachen Operationen abhängen. Wenn man den kleinen Unterschied von Post/Prefix betrachtet, dann ist eine einzige Multiplikation schon extrem viel schlimmer. Geschweige denn von Output.
-
antialias schrieb:
Also ich finde fast 5% Performanceunterschied nicht zu verachten. Besonders wenn man an zeitkritischen Applikationen arbeitet.
Außerdem ist es ein vector-Iterator. Das ist ja praktisch nur ein gekapselter Zeiger. Bei komplizierteren Iteratoren wie dem von map*, könnte ich mir vorstellen, dass der Unterschied sogar noch größer als 5% ist, weil die Optimierung komplizierter ist.
*: Bloß geraten, dass der kompliziert ist, kenne die Implementierung nicht. Jedenfalls wird es doch sicherlich Iteratoren geben, deren Zustand aus mehr als nur einem Pointer besteht.
-
Sequenzen iteriert man im allgemeinen sowieso per for_each und transform.
-
dineki89 schrieb:
Sequenzen iteriert man im allgemeinen sowieso per for_each und transform.
nur in Spezialfällen, wenn man bereits alle Funktionen fertig rumfliegen hat. Im Allgemeinen ist for_each häßlicher als eine for-Schleife, wenn man erstmal einen Funktor zusammenbasteln muss.
-
dineki89 schrieb:
Sequenzen iteriert man im allgemeinen sowieso per for_each und transform.
Ich mache das nie, viel zu mühsam. Ich glaube auch nicht dass "man" das "im allgemeinen" so macht.
Ich verwende
for(size_t i ... i < ... i++)oderBOOST_FOREACH.
(oder ganz selten mal Iteratoren "zu Fuss", also ohneBOOST_FOREACH)
-
otze schrieb:
dineki89 schrieb:
Sequenzen iteriert man im allgemeinen sowieso per for_each und transform.
nur in Spezialfällen, wenn man bereits alle Funktionen fertig rumfliegen hat. Im Allgemeinen ist for_each häßlicher als eine for-Schleife, wenn man erstmal einen Funktor zusammenbasteln muss.
Da dürfte sich mit den Lambdas von C++0x einiges Ändern.
BTW: War jmd. in Rapperswil den Bjarne und Herb Sutter gucken?
-
theta schrieb:
otze schrieb:
dineki89 schrieb:
Sequenzen iteriert man im allgemeinen sowieso per for_each und transform.
nur in Spezialfällen, wenn man bereits alle Funktionen fertig rumfliegen hat. Im Allgemeinen ist for_each häßlicher als eine for-Schleife, wenn man erstmal einen Funktor zusammenbasteln muss.
Da dürfte sich mit den Lambdas von C++0x einiges Ändern.
Wie willst du den mit Lambdas das for_each verbessern?
BTW: War jmd. in Rapperswil den Bjarne und Herb Sutter gucken?
Natürlich nicht.
-
www schrieb:
theta schrieb:
otze schrieb:
dineki89 schrieb:
Sequenzen iteriert man im allgemeinen sowieso per for_each und transform.
nur in Spezialfällen, wenn man bereits alle Funktionen fertig rumfliegen hat. Im Allgemeinen ist for_each häßlicher als eine for-Schleife, wenn man erstmal einen Funktor zusammenbasteln muss.
Da dürfte sich mit den Lambdas von C++0x einiges Ändern.
Wie willst du den mit Lambdas das for_each verbessern?
Dadurch, dass keine Funktoren mehr nötig sind, welche (Codierungs) Overhead mitbringen und nicht so lokal wie gwünscht sind.
-
Bei C++0x kann man auch gleich die "range-based for"-Schleife nehmen:
-
theta schrieb:
Wie willst du den mit Lambdas das for_each verbessern?
Dadurch, dass keine Funktoren mehr nötig sind, welche (Codierungs) Overhead mitbringen und nicht so lokal wie gwünscht sind.
Dadurch wird for_each auch nicht viel besser, sieht nur total kryptisch aus. range-based for sieht schon viel besser aus.
-
wie du meinst...