Performance Variablentausch (Min > Max): Selbstaufruf, By-Reference, ..?



  • Cpt_Future schrieb:

    Danke euch beiden, werds wohl mit der flotten XOR-Swap-Funktion von LordJaxom lösen!

    Woher nimmst du das wissen, dass diese Variante schneller ist?
    Ist auf einem x86 nämlich nicht der Fall.



  • Nimm einfach std::swap. Der Hersteller deiner Platform wird schon wissen, was am schnellsten ist. Die Funktion wird ja in fast allen Fällen geinlined und dann zahlt sich das Wissen des Herstellers aus.



  • Any schrieb:

    Cpt_Future schrieb:

    Danke euch beiden, werds wohl mit der flotten XOR-Swap-Funktion von LordJaxom lösen!

    Woher nimmst du das wissen, dass diese Variante schneller ist?
    Ist auf einem x86 nämlich nicht der Fall.

    Ich habe das Wissen nicht, ich habe nur angenommen, dass (wenige) bitweise Operationen schneller sind als das deklarieren neuer Variablen oder neue Funktionsaufrufe.

    Also werd ich wohl std::swap() nehmen, danke.



  • Any schrieb:

    Ist auf einem x86 nämlich nicht der Fall.

    Hält mein Kollege für ein Gerücht, was empfiehlst du denn?



  • Ich würde dem Kollegen nur glauben wenn er "Profiler" heißt. 😉



  • Also auf meinem Linux-x86 ist die lokale-Variable-Variante rund 30% schneller als die XOR-Variante... Ohne Optimierung...

    Mit -O2 sind beide annähernd gleich schnell 😮


  • Mod

    CStoll (off) schrieb:

    Ich vermute mal, swap() (als inline-Funktion deklariert) dürfte schneller sein - aber im Ernstfall müsstest du das praktisch ausprobieren.

    Zwei Punkte, die für swap() sprechen, wären noch:

    • Du mußt die < Überprüfung nur einmal machen
    • lokale Variablen der Funktion müssen nur einmal angelegt (und demzufolge auch nur einmal zerstört) werden

    ich denke, es hängt davon ab inwieweit der compiler damit zurecht kommt. man könnte z.b. den test unmittelbar in eine inline function auslagern, mit ein bisschen statischer analyse, könnte der optimierer sie möglicherweise z.T. eliminieren:

    bool PointInEllipse(long px, long py, long left, long top, long right, long bottom)
    {
        return left > right
            ? PointInEllipseImpl(px, py, left, top, right, bottom)
            : PointInEllipseImpl(px, py, right, top, left, bottom);
    }
    bool PointInEllipseImpl(long px, long py, long left, long top, long right, long bottom)
    {
    // ...
    }
    

    ob das hilft, kann nur der profiler verraten. in jedem fall zieht das argument mit den lokalen variablen nicht wirklich. wenn die swap variante benutzt wird, sollt es auf jeden fall std::swap sein - das ist schließlich dazu da, die optimale implementation auf der gegebenen plattform zu haben.

    inline void Swap(long &a, long &b)
    {
      a ^= b;
      b ^= a;
      a ^= b;
    }
    

    ist schlecht. es führt zu erheblichen abhängigkeiten in den registern und dürfte die meisten optimierer verwirren. im übrigen ist es nicht aliasing sicher, eine ganz unangenehme eigenschaft für ein swap (überleg, was bei swap(a,a) rauskommt).



  • kurzum ich bleib besser bei
    long c = a;
    a = b;
    b = c;

    Denn std::swap() ist offenbar nicht auf allen Plattformen die wir einsetzen vorhanden und wenn ^= wie du sagst nicht so optimierbar ist, lass ichs einfach.
    So relevant ist die Funktion(sgeschwindigkeit) jetzt auch nicht.
    Danke euch.



  • Ich sehe immer noch keinen Grund std::swap nicht einzusetzen. Notfalls programmiert man es sich nach.



  • Ich bin Praktikant, soll eigentlich nur Unit-Tests machen, und mein Betreuer meint "std::swap() sollten wir nicht nehmen, das steht auf einigen Plattformen nicht zur Verfügung."
    Da hat er nunmal das letzte Wort. Es einfach mal so nachzuprogrammieren für bestimmte Plattformen, da fehlt mir das Wissen.


Anmelden zum Antworten