code design Problem:



  • Hallo, ich habe ein Problem wie ich ein Programm designen soll.

    Es geht um Folgendes:
    Ich habe ein Programm, welches in einer Schleife einige 1000000 mal ausgeführt werden soll und so schnell wie möglich sein muß!

    Jetzt möchte ich aber 3 varianten dieser Methode schreiben, die sich leider nicht durch die Pararmeter sondern nur durch eine einzige Zeile unterscheiden.
    Jetzt könnte ich das Problem ja auf 2 arten lösen. Entweder ich kopiere den Code und erstelle 3 Varianten, die sich nur in dieser einen zeile unterscheiden, oder ich lasse zur Laufzeit dynamisch abfragen, welche Variante es sein soll und rufe dementsprechend diese eine Zeile jeweils entsprechend auf.

    Nun ist das Problem aber, dass ja bei jedem Durchlauf der 1000000 Durchläufe testen würde, welche Version gerade erwünscht ist. So viele Vergleiche sind ja micht so schnell außerdem müßte ich ja die entsprechende Zeile aufrufen und hätte so zusätzliche Sprunganweisungen.

    Also wollte ich mich für die Variante mit dem duplizierten code entscheiden.
    Nun meine Frage:

    Entsteht durch duplizierten code weitere Nachteile außer erhöhter Speicherbedarf?
    Ist dies generell wirklich die schnellere lösung?
    Oder gibt es noch bessere Ideen?

    (Denn ich möchte es umgehen beide Ideen implementieren zu müssen, außerdem ist durch das Anwendungsfeld ein laufzeit Test zum ermitteln der Geschwindigkeit fast außgeschlossen)



  • template. damit kansnte zur compilezeit den parameter festlegen und der macht drei unabhängige funktionen draus. ist also genausoschnell wie 3 funktionen aber hast innen das if stehen statt so viel code zu triplizieren (in memoriam an kohls trialog).



  • wie so oft im leben ist die mitte die beste lösung. ein code der 1000000 befehle hat, passt nichtmal in den 2nd level cache, es dürfte das langsammste sein diesen speicher zu ziehen und nicht die befehle auszuführen, source der zeitkritisch ist sollte in maximal 16kb passen wenn er überall gut laufen soll.

    wenn du also eine der 3 funktionen in einer schleife ausführen möchtest, kopier dir die funktion 20 mal und führe diese schleife dann 50000 mal aus.

    zudem, wenn es immer die selbe funktion ist die du 10000000 aufrufen möchtest, kannst du einen functionpointer benutzen.

    aber oft ist eine optimierung am algorithmus sehr viel effektiver als code-optimierungen.

    rapso->greetes();



  • vhngzhjzf schrieb:

    Ich habe ein Programm, welches in einer Schleife einige 1000000 mal ausgeführt werden soll und so schnell wie möglich sein muß!

    Jetzt möchte ich aber 3 varianten dieser Methode schreiben, die sich leider nicht durch die Pararmeter sondern nur durch eine einzige Zeile unterscheiden.
    Jetzt könnte ich das Problem ja auf 2 arten lösen. Entweder ich kopiere den Code und erstelle 3 Varianten, die sich nur in dieser einen zeile unterscheiden, oder ich lasse zur Laufzeit dynamisch abfragen, welche Variante es sein soll und rufe dementsprechend diese eine Zeile jeweils entsprechend auf.

    Nun ist das Problem aber, dass ja bei jedem Durchlauf der 1000000 Durchläufe testen würde, welche Version gerade erwünscht ist. So viele Vergleiche sind ja micht so schnell außerdem müßte ich ja die entsprechende Zeile aufrufen und hätte so zusätzliche Sprunganweisungen.

    Also wollte ich mich für die Variante mit dem duplizierten code entscheiden.

    Mach's so. Eine zusätzliche IF-Abfrage bremst den Code bloß aus.

    Je weniger Code Du in Deiner Schleife hast, desto besser. Verschieb so viel wie geht nach außerhalb der Schleife.

    Falls Du einen Compiler mit Optimizer hast, verwende Inlining für die kleinen Funktionen (d.h. bei C++ z.B. als "inline" deklarieren und Inlining des Compilers einschalten). Sehr geschickt ist es auch, Code der zu optimieren ist, in ein extra Modul auszulagern und nur dort die Optimierung einzuschalten (vermindert Risiko, daß sich Compiler-Bugs auf die Code-Erzeugung auswirken; Optimizer sind meist fehlerbehaftet).

    Falls das nicht genug Speed bringt, überprüfe, ob Dein Algorithmus vielleicht zu umständlich ist: Je einfacher der Algorithmus, um so schneller kann er laufen. Aber auch besondere Konstruktionen wie Hashtabellen (Maps) usw. können einiges an Performance bringen.



  • rapso schrieb:

    wie so oft im leben ist die mitte die beste lösung. ein code der 1000000 befehle hat, passt nichtmal in den 2nd level cache, es dürfte das langsammste sein diesen speicher zu ziehen und nicht die befehle auszuführen, source der zeitkritisch ist sollte in maximal 16kb passen wenn er überall gut laufen soll.

    Nanu rapso 😕
    Da komm ich nicht mit. Ich habe gehört, dass manche Compiler den Code kleiner Schleifen, die nur ein paar Durchäufe haben, zur Optimierung hintereinander kopieren.
    Aber dazu wird ja bei einer Schleife mit 1000000 Durchläufen der Compiler nicht in Versuchung geraten, oder?



  • SeppSchrot schrieb:

    rapso schrieb:

    wie so oft im leben ist die mitte die beste lösung. ein code der 1000000 befehle hat, passt nichtmal in den 2nd level cache, es dürfte das langsammste sein diesen speicher zu ziehen und nicht die befehle auszuführen, source der zeitkritisch ist sollte in maximal 16kb passen wenn er überall gut laufen soll.

    Nanu rapso 😕
    Da komm ich nicht mit. Ich habe gehört, dass manche Compiler den Code kleiner Schleifen, die nur ein paar Durchäufe haben, zur Optimierung hintereinander kopieren.
    Aber dazu wird ja bei einer Schleife mit 1000000 Durchläufen der Compiler nicht in Versuchung geraten, oder?

    Naja, aber es gibt ja noch partial-loop-unrolling oder SIMD.


Anmelden zum Antworten