iterator vs. normalen traversion? (Vector)



  • 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.



  • 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???

    Wenn der Himmel wirklich blau ist, wieso schreibt man dann Koffer mit K und nicht mit G???



  • hustbaer schrieb:

    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???

    Wenn der Himmel wirklich blau ist, wieso schreibt man dann Koffer mit K und nicht mit G???

    weil der himmel nicht für alle blau ist... je nach aufnehmbarem spektrum eben. zudem: schonmal nachts den himmel angeschaut? siehste...



  • @muffmolch

    wieso sollte der iterator überhaupt langsamer sein?
    in meiner stl implementation ist der iterator eines vector<int> ein int*. Es lassen sich also keinerlei aussagen darüber treffen, ausser die, dass bei deiner implementation der iterator langsam ist.



  • ich habs vor ner ganzen weile auch mal ausprobiert und da war iterator schneller.

    index zugriff war so schnell wie index zugriff auf normales array
    Iterator war so schnell wie pointer zugriff auf normales array, also schneller



  • einigen wir uns doch einfach darauf:
    die letztendliche effizienz hängt von der implementierung, dem compiler und den verwendeten optimierugnen ab.
    eine allgemeingültige aussage ist daher nicht ohne weiters möglich.
    im standard ist diebezüglich nichts definiert.


Anmelden zum Antworten