Frage zur Optimierung von Programmcode



  • Hallo!
    Ich hab kurz mal 'ne Frage.
    Gegeben ich hab zwei Schleifen:

    int dimension = a.getDimension();
    float dotProduct = 0.0;
    for(int i = 0; i < dimension; i++)
    {
        dotProduct += a.coordinates_[i] * b.coordinates_[i];
    }
    return dotProduct;
    

    und 2.

    float dotProduct = 0.0;
    for(int i = 0; i < a.getDimension(); i++)
    {
        dotProduct += a.coordinates_[i] * b.coordinates_[i];
    }
    return dotProduct;
    

    Ich hab irgendwo mal gelesen, dass die zweite Schleife langsamer ist, als die erste, da hier ja in jedem Druchgang die Funktion getDimension aufgerufen wird.
    Stimmt das oder sind die Unterschiede so klein bzw. die Compiler soweit optimiert, dass das keinen Unterschied macht?

    Danke,
    S1ckness.



  • S1ckness schrieb:

    Ich hab irgendwo mal gelesen, dass die zweite Schleife langsamer ist, als die erste, da hier ja in jedem Druchgang die Funktion getDimension aufgerufen wird.
    Stimmt das oder sind die Unterschiede so klein bzw. die Compiler soweit optimiert, dass das keinen Unterschied macht?

    Das kommt auf den Compiler an, wie es das Beispiel mit Iteratoren (vorspeichern oder nicht) von SeppJ gezeigt hat. Und wenn es überhaupt ins Gewicht fällt, dann wohl erst bei einer Anzahl von min. ein paar Millionen Iterationen. Davon abgesehen, was passiert, wenn du innerhalb der Schleife Dimension veränderst. Dann hast du, wenn du den Wert vorspeicherst, ein Problem, weil die Schleife nicht auf die Änderung reagieren kann. Und schon allein aus diesem Grund würde ich 2. nehmen, sodass alles schön dynamisch ist.



  • Kann es sein, dass du nach std::inner_product suchst?

    Ansonsten hilft bei so was nur messen, messen, messen.



  • Normal nehm ich auch die 2. Schleife. Dachte mir nur, dass ich, wenn das wirklich ins Gewicht fallen würde, zumindest die Schleifen, bei denen ich weiß, dass die Bedingung konstant ist, hätte umbauen können. So werd ich dann aber wohl bei 2. bleiben.

    Nein, die Schleife dient zur Implementierung des Skalarprodukts zweier Vektoren. Im Englischen dann halt "dot product".



  • S1cknessGast schrieb:

    Nein, die Schleife dient zur Implementierung des Skalarprodukts zweier Vektoren. Im Englischen dann halt "dot product".

    Wenn das Skalarprodukt eines Vektorraums durch die Einheitsmatrix beschrieben wird, wie es bei dir der Fall zu sein scheint, ist das innere Produkt mit dem Skalarprodukt äquivalent. Was du da ausrechnest, ist jedenfalls das innere Produkt und genau das, was std::inner_product auch ausrechnet.



  • Oh, das innere Produkt kannte ich noch gar nicht.
    Ich werd dennoch bei meiner Implementation bleiben, da ich mit Qt arbeite und dabei möglichst auf die Standardbibliothek verzichten möchte, sonst hätte ich am Ende 'nen Mix aus beidem, Qt und STL.



  • LOL. Du nutzt natürlich so viel wie möglich die STL, und so wenig wie möglich Qt. Am besten kapselst du Qt gleich ganz weg, sodass der Hauptteil deiner Applikation unabhängig bleibt. Aber auf die STL zu verzichten macht mal sehr wenig Sinn. Na gut, wenn du Qt statt als Library gleich als Spracherweiterung sehen willst, kann man das vielleicht machen. Ob das aber wieder Sinn macht, wage ich zu bezweifeln. (Ich mag Qt aber auch nicht.. ;))



  • Würdest du mir erleutern warum ich STL anstatt QTL nutzen sollte?
    Ich benutze Qt generell zur GUI-Programmiernung. Warum sollte ich dann STL und QTL kombinieren, wenn ich auch nur eins von beiden nutzen kann?
    Performancemäßig tun sich beide nichts. Der Code ist größtenteils kompatibel.



  • Damit der größte Teil deines Codes portabel und unabhängig von Qt bleibt? Ist eigentlich offensichtlich.



  • Wer OpenGL nutzt, macht sich abhängig von OpenGL, wer Boost nutzt macht sich abhängig von Boost, etc.
    Ist doch immer so, wenn ich eine API verwende. Und da ich, wie gesagt, generell meine GUIs mit Qt programmiere, sehe ich da nicht das Problem Qt auch für meine Vector-Klasse zu verwenden. Und STL und QTL sind wie gesagt nahezu kompatibel. Ich könnte, wenn nötig, durch kleinere Änderungen sofort auf ST, zumindest alles was nicht mit der GUI zu tun hat, umstellen. Natürlich wäre es mit STL einfacher die Klasse auch in anderen Projekten zu verwenden. Nur das brauche ich (im Moment) nicht.



  • Du kannst std::inner_product auch mit einem QVector verwenden... Qt hat iteratoren als Schnittstelle für seine Container.

    Generell ist Qt weitgehend STL kompatibel.



  • S1ckness schrieb:

    Wer OpenGL nutzt, macht sich abhängig von OpenGL

    Genau. Deswegen kapselt man den Quatsch ja auch weg, damit man ihn bei Bedarf austauschen kann. 😉



  • S1ckness schrieb:

    Wer OpenGL nutzt, macht sich abhängig von OpenGL, wer Boost nutzt macht sich abhängig von Boost, etc.

    Aus Praxiserfahrung kann ich dir nur versichern, das man dennoch Abhängigkeiten begrenzen sollte, gerade bei den Bibliotheken, die man für die Darstellung verwendet. STL und boost sind dabei eher unproblematisch da die eigentlich immer vorliegen, OpenGL könnte aber z.B. durch DirectX ersetzt werden (oder umgekehrt), die Weiterentwicklung eines UI-Framework könnte einschlafen...

    Ich würde immer boost und STL vorziehen, bevor ich auch Abhängigkeiten eines externen Frameworks gehe, das wesentlich weniger standardisiert ist.

    S1ckness schrieb:

    Ist doch immer so, wenn ich eine API verwende. Und da ich, wie gesagt, generell meine GUIs mit Qt programmiere, sehe ich da nicht das Problem Qt auch für meine Vector-Klasse zu verwenden...

    Es gab eine Zeit in der die Qt-Entwicklung als gefährdet angesehen wurde. Und aus eigener Erfahrung: Es ist immer möglich das man auf das falsche Pferd gesetzt hat. Da ist es dann von Vorteil wenn zumindest die eigentliche Programmlogik möglichst portabel ist.



  • Gut, überredet. Ich werd dann wohl bei zukünftigen Projekten auf STL und Boost zumindest für den Kern des Programms setzen. GUI werde ich soweit es geht mit Qt machen, da ich das Framework einfach gern mag 🙂
    Ich mach das ganze ja nur hobbiemäßig. Es geht hier ja nicht um irgendwelche komerziellen Projekte. Ich verwende die Programme meist nur selbst oder stelle sie Freunden, etc. bereit.

    Danke für eure "Aufklärung" 🙂
    S1ckness



  • Qt ist wie ein Dildo. Es ist nicht so toll, aber es funktioniert. :p



  • Welche GUI-API bevorzugt ihr denn?
    Ich seh nicht was so schlecht an Qt sein soll. Damit, dass das alles nicht nativ ist, kann ich bei meinen Projekten glaub ich leben. Würd ich das beruflich machen, würd ich denk ich auch mehr auf Protabilität, Kapselung, etc. achten 🙂



  • IMO gibt es derzeit kein einziges, schön designtes GUI Framework.



  • 314159265358979 schrieb:

    Qt ist wie ein Dildo. Es ist nicht so toll, aber es funktioniert. :p

    Du hast mit beiden genug Erfahrung, um das beurteilen zu können?

    Qt geht schon in Ordnung. Ich persönlich bevorzuge gtkmm, wenn ich es mir aussuchen kann, aber ich musste auch schon mit wx und MFC arbeiten, also wäre Qt nichts, weswegen ich mir die Haare ausrisse.



  • seldon schrieb:

    Du hast mit beiden genug Erfahrung, um das beurteilen zu können?

    ^.-



  • S1ckness schrieb:

    Hallo!
    Ich hab kurz mal 'ne Frage.
    Gegeben ich hab zwei Schleifen:

    int dimension = a.getDimension();
    float dotProduct = 0.0;
    for(int i = 0; i < dimension; i++)
    {
        dotProduct += a.coordinates_[i] * b.coordinates_[i];
    }
    return dotProduct;
    

    und 2.

    float dotProduct = 0.0;
    for(int i = 0; i < a.getDimension(); i++)
    {
        dotProduct += a.coordinates_[i] * b.coordinates_[i];
    }
    return dotProduct;
    

    Ich hab irgendwo mal gelesen, dass die zweite Schleife langsamer ist, als die erste, da hier ja in jedem Druchgang die Funktion getDimension aufgerufen wird.
    Stimmt das oder sind die Unterschiede so klein bzw. die Compiler soweit optimiert, dass das keinen Unterschied macht?

    Danke,
    S1ckness.

    Noch mal zur Verdeutlichung des genauen Problems. Tatsächlich wird bei der 2. Variante jedes mal die Methode getDimension aufgerufen. Aber da wir nicht sehen, wie diese Methode implementiert ist, lässt sich nicht sagen, ob es relevant ist. In der Regel sind solche Funktionen im Header inline definiert und liefern den Wert einer privaten Variablen zurück. Das kann der Compiler einfach weg optimieren und es gibt keinen Unterschied der 2 Varianten. Anders ist es, wenn die Methode nicht Inline ist. Oder eben komplizierte Sachen ausführen muss. Ist a beispielsweise eine verkettete Liste könnte getDimension bedeuten, dass die Liste durchlaufen wird, um festzustellen, wie viele Elemente die Liste hat. Das kann der Compiler auch bei inline-code wahrscheinlich nicht weg optimieren. Da ist die 2. Variante tatsächlich dann teurer.


Anmelden zum Antworten