iterator vs. normalen traversion? (Vector)



  • std:vector<CRoute*> m_paRoute;
    

    Iterator:

    std::vector<CRoute*>::iterator itElem;
    for(itElem= temp.m_paRoute.begin(); itElem!= temp.m_paRoute.end(); itElem++)
       m_paRoute.push_back(new CRoute((**itElem)));
    

    Traversion:

    for(int i=0; i< temp.m_paRoute.size(); i++)
       m_paRoute.pushback(new CRoute(temp.n_paRoute.at(i)));
    

    was ist schneller /besser/ effizienter/ sicherer?

    Grüße



  • Der Iterator ist natürlich sicherer, da du (wie leider viele andere) die Traversion potentiell Fehlerhaft geschrieben hast.



  • was ist fehlerhaft?



  • rüdiger schrieb:

    Der Iterator ist natürlich sicherer, da du (wie leider viele andere) die Traversion potentiell Fehlerhaft geschrieben hast.

    diese potenz kann er auch beim implementieren der iterator-version an den tag legen, oder meinst du was spezielles was ich uebersehe?



  • BorisDieKlinge schrieb:

    was ist fehlerhaft?

    du benutzt einen Integer. std::size_t wäre hier angebracht oder zumindest ein anderer unsigned-Typ. Wenn du die Warnstufe bei deinem Compiler hochstellst sollte er dich sogar warnen. (Siehe dir den Rückgabetyp von std::vector<T>::size an).



  • edit

    meine erfahrungswerte mit gcc3.5, 4.01, icc 8.x, VS Studio Compiler ab 4.0):

    BorisDieKlinge schrieb:

    was ist schneller

    Zugriff über den Indexer

    BorisDieKlinge schrieb:

    was ist besser

    das hängt immer vom anwendungsfall ab:
    - ist performance gefragt: indexer
    - ist sicherheut gefragt: .at(i)

    BorisDieKlinge schrieb:

    was ist effizienter

    Indexer

    BorisDieKlinge schrieb:

    sicherer

    iterator oder .at(...)

    BTW: besser ++it als it++ verwenden, dann spart man eine unnötige interne iterator kopie (liegt an der implementierung von post- und prefix-operatoren



  • muffmolch schrieb:

    BorisDieKlinge schrieb:

    was ist schneller

    Zugriff über den Indexer

    [...]

    BorisDieKlinge schrieb:

    was ist effizienter

    Indexer

    äh? ist das eine Vermutung oder hast du auch eine Begrüdung für deine These?



  • rüdiger schrieb:

    äh? ist das eine Vermutung oder hast du auch eine Begrüdung für deine These?

    7 Jahre strömungscode entwicklung, bei denen ausschließlich mit langen arrays hantiert wird. und ich rede jetzt von reiner zugriffszeit.
    allein wenn man sich die ierator implementierung anschaut, so greift man beim indexer direkt auf die speicherstelle zu und beim iterator eben nicht.
    jedenfalls konnte unser compiler (gcc3.x, icc unter linux und der vs 200x) bei der iterator version nie die performance des indexers erreichen.
    und da unser chef generell etwas gegen OO bei berechnungskerneln hat... mussten wir eben ein paar performance tests machen

    edit: wobei ich bei indexer den index-operator meine und nicht .at(i).
    .at(i) und iteratoren hatten wir auch mal verglichen, aber da gab es glaub keinen nenenswerten unterschied und je nach compile rund optionen gab es da unterschiedliche ergebnisse.



  • rüdiger meinte das anders: wo steht im Standard, das der Index-Operator _garantiert_ schneller ist? Genau das sagst du implizit in deinem Posting. Aber darauf kann man sich nicht verlassen, das der Index-Op schneller ist, als z.B. die at-Methode. Klar, dadurch das der Index-Op keine Bereichsprüfung machen _muss_, ist er in den Implementierungen meistens schneller. ABER, du kannst genauso an eine Implementierung geraten, die den Index-Op so implementiert, das er sicher wie at() ist. Und dann? Dann schaut man beim nächsten Praxiseinsatz ganz schön dumm aus der Wäsche, weil das Programm langsamer gewortden ist. 😉

    Sicherlich hast du, was die gängigen Implementierungen angeh, Recht. Aber du kannst nicht einfach die Antwort so geben, als sei das irgendwo definiert. rüdigers Frage war sicherlich provokativ, aber sollte auch für das nächste Mal zu denken geben.

    EDIT: Bjarne Stroustrup hatte z.B. für den C++2009-Standard vorgeschlagen, für alle Index-Ops der Container und Strings, eine Bereichsprüfung vorzuschreiben. Damit ist er meines Wissens nicht durch gekommen, zeigt aber, das deine Aussage ganz einfach nicht garantiert ist. Weil morgen könnte deine Aussage ganz einfach definitiv falsch sein. Und heute ist sie nicht garantiert.



  • da hast du wohl recht! dahe rhabe ich obigen eintrag editiert und demenstprechend "meine erfahrungswerte" und die compiler die wir verwendet haben aufgezählt (zumindest die, die mir eingefallen sind).
    der standard sagt meines erachtens darüber nichts aus.
    eine optionale bereichsüberprüfung beim indexer wäre ne feine sache, denn es ist schlichtweg nicht möglich mal eben von [i] auf .at(i) im gesammten code zu switchen. eine mögliche präprozessor definition wäre da aber auch schon ausreichend gewesen...

    sorry, wenn ich mich missverständlich ausgedrückt habe



  • muffmolch schrieb:

    meine erfahrungswerte mit gcc3.5, 4.01, icc 8.x, VS Studio Compiler ab 4.0):

    Mit welchen Optimierungen? Ich kann mir eigentlich nicht vorstellen, dass es ein halbwegs guter Compiler nicht schafft, das Overhead eines Iterators für einen Vektor herauszuoptimieren. Im Zweifelsfall ist das doch einfach nur ein Zeiger auf die Elemente, d.h. er macht genau das, was Du beim Indexer anführst: direkter Zugriff auf eine Speicherzelle.



  • Konrad Rudolph schrieb:

    muffmolch schrieb:

    meine erfahrungswerte mit gcc3.5, 4.01, icc 8.x, VS Studio Compiler ab 4.0):

    Mit welchen Optimierungen? Ich kann mir eigentlich nicht vorstellen, dass es ein halbwegs guter Compiler nicht schafft, das Overhead eines Iterators für einen Vektor herauszuoptimieren. Im Zweifelsfall ist das doch einfach nur ein Zeiger auf die Elemente, d.h. er macht genau das, was Du beim Indexer anführst: direkter Zugriff auf eine Speicherzelle.

    gcc
    ADD_CXX_FLAGS("-O3 -march=athlon64 -fomit-frame-pointer -finline-functions -funroll-all-loops -fpermissive")

    vs:
    weitesgehend alle geschwindigkeitsoptimierungen waren aktiviert, wenn ich es richtig in erinnerung habe.

    PS: was ich mir noch weniger vorstellen kann ist: wenn ein compiler die iteratoren weg compilieren kann, weiso sind fast alle neuen tollen compiler nicht in der lage mit dem schlüsselwort extern bei templates umzugehen???



  • muffmolch schrieb:

    PS: was ich mir noch weniger vorstellen kann ist: wenn ein compiler die iteratoren weg compilieren kann, weiso sind fast alle neuen tollen compiler nicht in der lage mit dem schlüsselwort extern bei templates umzugehen???

    Na ja. Für 'extern' müssen sich die Compilerhersteller schon intensiv Gedanken um ein geeignetes Binärformat machen, in dem der Code vor dem Linken abgelegt werden kann. Das ist schon mit einigem Aufwand verbunden und solange es hier keine Standards geht und jeder sein eigenes Süppchen brüht, wäre das sowieso chaotisch, da nicht portabel.

    Beim Iterator hingegen würde ich doch eigentlich vermuten, dass hier wirklich nur einige triviale Funktionen geinlined werden sollten. Dachte ich. Anscheinend irre ich mich ja.



  • Artchi schrieb:

    EDIT: Bjarne Stroustrup hatte z.B. für den C++2009-Standard vorgeschlagen, für alle Index-Ops der Container und Strings, eine Bereichsprüfung vorzuschreiben.

    das hat er bestimmt nur als scherz gemeint...



  • muffloch! Du meinst export? Das werden wir nie erleben, weil viel zu aufwändig zu implementieren. Es gab schon mal einen Vorschlag das 'export' aus C++2009 zu verbannen, so extrem ist die Geschichte (export war der größte Fehler des Komitees!). Wurde aber auch abgelehnt.

    Optimierungen haben eine bessere Wertschöpfung für die Industrie, als ein Verstecken von Template-Code. Deswegen optimieren die Compiler alles so schlau.



  • Artchi schrieb:

    Optimierungen haben eine bessere Wertschöpfung für die Industrie, als ein Verstecken von Template-Code. Deswegen optimieren die Compiler alles so schlau.

    Ich glaube da geht es weniger um ein Verstecken als eher um ein Beschleunigen der Kompilation und das wäre ja durchaus (von ganz erheblichem!) Nutzen.



  • letzterem kann ich nur zustimmen...



  • Ich hätte eher erwartet, dass die Iteratorversion schneller ist als die Indexversion. Grundsätzlich machen diese Folgendes:

    Index:
    1. Index inkrementieren
    2. Index zum Basiszeiger addieren
    3. Resultierenden Zeiger dereferenzieren

    Iterator:
    a. Iterator inkrementieren
    b. Iterator dereferenzieren

    Ich denke, dass viele Prozessoren die Schritte 2 und 3 gleichzeitig ausführen können. Aber gilt dies für alle Indexgrößen?

    Ist die Iteratorvariante immer noch langsamer, wenn man einen Zeiger als Iterator nimmt?



  • Konrad Rudolph schrieb:

    Artchi schrieb:

    Optimierungen haben eine bessere Wertschöpfung für die Industrie, als ein Verstecken von Template-Code. Deswegen optimieren die Compiler alles so schlau.

    Ich glaube da geht es weniger um ein Verstecken als eher um ein Beschleunigen der Kompilation und das wäre ja durchaus (von ganz erheblichem!) Nutzen.

    Schnelleres Kompilieren geht heute mit Precompiled Headers. Wenn ich SmartWin++ benutze, dauert das Kompilieren ohne PCH sehr lange (habe leider keine Zeit gestoppt). Mit PCH wird das ganze um ein vielfaches gekürzt! Seit dem benutze ich immer PCHs. Sehe hier also keinen Grund auf export angewiesen zu sein, da PCHs heute (hoffentlich) zu den Features gängiger Compiler gehört.

    Die Forderung nach export ist eher die Möglichkeit für das verstecken von Sourcecode. Für Closedsource-Libs eindeutig ein Argument gegen Templates.

    Weiterhin: ist das Ergebnis beim Cameau auch wirklich mehr Kompile-Performance? Ich kann mich irren, aber laut Cameau-Erfahrungsbericht ist da nichts schneller. Der Bericht hat sich eher niederschmetternd gelsen. Alles eher noch kompilizierter. Ist aber schon seeehr lange her, als ich deren Dokument gelesen hatte.



  • Da ich in VC bisher einige Probleme mit Standard-Bibliotheken in stdafx hatte, habe ich seitdem auf das Verwenden vorkompilierter Header verzichtet. Vielleicht muss ich mich damit nochmal auseinandersetzen denn gerade in Verbindung mit Spirit wäre das ja schon recht nützlich.


Anmelden zum Antworten