Lohnt sich diese Optimierung



  • Priorität sollte ganz klar die Übersichtlichkeit haben! Erst wenn man zweifelsfrei feststellen kann, dass ein konkretes Szenario optimiert werden muss, sollte man sich auch dran setzen.



  • Naja bevor du dir Gedanken über solche (Mikro-)Optimierungen machst solltest du dir lieber welche über eine sinnvolle Namenskonvention machen.

    Klar benützt jeder von uns solche Bezeichner für erste Prototyen.
    Bei dir sollten aber eigentlich die Alarmglocken klingeln sobald du in einer Funktion mehr als einmal den selben Namen für unterschiedliche Variablen verwendest.



  • Also in kurzen Funktionen habe ich meine lokalen Variablen gerne kurz. Meine Membervariablen sind natürlich länger und eindeutiger.



  • hi

    Badestrand schrieb:

    Priorität sollte ganz klar die Übersichtlichkeit haben! Erst wenn man zweifelsfrei feststellen kann, dass ein konkretes Szenario optimiert werden muss, sollte man sich auch dran setzen.

    dieses denken scheint immer mehr in mode gekommen zu sein. wie rean schon sagt koennte der konstruktor einer klasse aufwendige arbeiten machen und der thread-ersteller sagte nicht das es sich ausdruecklich auf PODs bezieht.
    man sollte sich daher waehrend der programmierung schon ueberlegen bzw. bei fremdklassen nachsehen was der konstruktor so treibt.

    Meep Meep



  • Klar sollte Übersichtlichkeit Priorität haben. Wenn man allerdings schon während der Programmierung bestimmte Optimierungen ohne zusätzlichen Aufwand vorgenommen werden können, dann sehe ich darin keinen Nachteil.



  • AlphaWolf schrieb:

    Ich denke es wird klar was ich meine. Wenn beide Methoden semantisch das gleiche tuen lohnt es sich die Variable au0erhalb der Schleife zu deklarieren?

    Grundsätzlich würde ich Variablen dort deklarieren, wo sie tatsächlich verwendet werden, und nicht irgendwo anders. Völlig unabhängig von Optimierungsstrategien.

    1. Sieht man leichter was zusammengehört
    2. Sieht man eher was man auslagern kann
    3. Läuft nicht so leicht Gefahr das man beim Ändern etwas übersieht
    4. Kann man sie dann eher sinnvoll initialisieren

    Es gab lange eine Fraktion die meinte alle Variablen müssen am Anfang eines Blockes (z.B. Funktion) deklariert werden, inzwischen hat sich eher der Ansatz durchgesetzt sie wirklich erst dort zu deklarieren wo man sie auch anwendet.

    cu André



  • it0101@loggedoff schrieb:

    Wenn man allerdings schon während der Programmierung bestimmte Optimierungen ohne zusätzlichen Aufwand vorgenommen werden können, dann sehe ich darin keinen Nachteil.

    dito, solange darunter die Lesbarkeit nicht leidet.



  • asc schrieb:

    Es gab lange eine Fraktion die meinte alle Variablen müssen am Anfang eines Blockes (z.B. Funktion) deklariert werden

    Ja, das hat mir mein Ausbilder auch noch beigebracht. Am Anfang der 1000-Zeilen-Funktion sollten alle 70 Variablen deklariert werden! 😃 Mittlerweile sehe ich das ein klein wenig anders...



  • _matze schrieb:

    Ja, das hat mir mein Ausbilder auch noch beigebracht. Am Anfang der 1000-Zeilen-Funktion sollten alle 70 Variablen deklariert werden! 😃 Mittlerweile sehe ich das ein klein wenig anders...

    Lass mich raten: In mindestens zweierlei Weise? (Also mir ist zu der Anfangsinitialisierung auch die Funktion viel zu lang...).

    Aber diese Ansicht hält sich noch immer in den Köpfen vieler die so Ausgebildet wurden sind (noch vor einem halben Jahr hatte ich aktiv mit so einem im Projekt zu tun)...



  • asc schrieb:

    Also mir ist zu der Anfangsinitialisierung auch die Funktion viel zu lang...

    Na sicher, mir auch (deshalb habe ich es auch erwähnt). Ich bin nicht so radikal, dass ich Funktionen über 10 Zeilen gleich verteufele, aber viel mehr sollten es im Normalfall dann doch nicht sein (zumal sich das Auslagern von Codeabschnitten in neue Funktionen im Laufe eines Projekts meist automatisch bezahlt macht, ganz abgesehen von der gewonnenen Übersicht).

    Trotzdem muss ich meinem Ausbilder zugute halten, dass er (zunächst im Alleingang, war eine sehr kleine Firma) einen nahezu hundertprozentig bugfreien Code produziert hat! Von den Kunden kamen eigentlich immer nur Änderungswünsche, nur in gaaanz seltenen Fällen hat sich wirklich mal jemand wegen einer Fehlfunktion gemeldet. Das ist auch schon was Wert. Unser Bugtracker heute bleibt immer schön im 3-stelligen Bereich...



  • Ich wage zu behaupten, dass die erste Version genauso gut schneller sein kann als die erste. Angeblich optimieren viele Compiler besser, wenn die Lebensdauer eines Objekts kürzer ist.
    Aber ganz grundsätzlich halte ich keine Variante davon für eine "Optimierung", bevor deren überlegene Schnelligkeit nicht im konkreten Anwendungsfall nachgewiesen ist.
    geloescht



  • Um zum Thema zurück zu kommen:

    Jedes Objekt, das innerhalb einer Schleife definiert wird, wird auch bei jedem Durchgang neu erschaffen (rein theoretisch).



  • EOP schrieb:

    (rein theoretisch).

    Mit Betonung auf theoretisch. Häufig wird ein Compiler nicht bei jedem Schleifendurchlauf den kompletten Block auf den Stack pushen und am Ende der Schleife wieder runternehmen sondern ihn lassen bis die Abbruchbedingung erfüllt ist. Im Falle von PODs macht das also keinen Unterschied, einen ähnlichen Fall gabs vor kurzem hier im Forum wo genau das beobachtet wurde.
    Bei dicken Konstruktoren wo Ressourcen angefordert werden usw. die der Compiler schlecht wegoptimieren kann, könnte es unter Umständen einen Vorteil bringen, die Konstruktion außerhalb der Schleife vorzunehmen - allerdings sollte man dem Compiler die Chance lassen das mit der Optimierung vieleicht doch selbst besser hinzubekommen, sich überlegen ob man das der Übersichtlichkeit zumuten kann, ein Objekt außerhalb der Schleife zu konstruieren, obwohl man es nur innerhalb braucht und am Ende mal mit dem Profiler nachschauen ob die "Optimierung" wirklich eine ist...

    asc schrieb:

    Es gab lange eine Fraktion die meinte alle Variablen müssen am Anfang eines Blockes (z.B. Funktion) deklariert werden

    Die Fraktion hatte da auch gute Gründe für:
    - "Das war schon immer so"
    - "printf("Das muss man so machen, das geht garnicht anders", %s) - Wie, bei C++ ist einiges anders???"
    - "Als ich noch nicht meine dritten hatte musste ich mich bei FORTRAN durch COMMON-Blöcke und so beißen..."
    *SCNR* 🤡



  • pumuckl schrieb:

    Bei dicken Konstruktoren wo Ressourcen angefordert werden usw. die der Compiler schlecht wegoptimieren kann, könnte es unter Umständen einen Vorteil bringen, die Konstruktion außerhalb der Schleife vorzunehmen - allerdings sollte man dem Compiler die Chance lassen das mit der Optimierung vieleicht doch selbst besser hinzubekommen, sich überlegen ob man das der Übersichtlichkeit zumuten kann, ein Objekt außerhalb der Schleife zu konstruieren, obwohl man es nur innerhalb braucht und am Ende mal mit dem Profiler nachschauen ob die "Optimierung" wirklich eine ist...

    Das wäre ein Fall, wo ich das Objekt zuerst ausserhalb der Schleife deklarieren würde, und erst bei dramatischen Übersichtlichkeitsverlusten überlege ich mir das Ganze nochmals. Aber dramatische Übersichtlichkeitsverluste - reden wir nicht ein wenig an der Realität vorbei? Wenn man einigermassen überblickbare Funktionen hat, macht es von der Lesbarkeit wirklich kaum einen Unterschied aus, ob nun ein Objekt vor oder nach dem Beginn der Schleife deklariert wird. Okay, innerhalb hat man noch die Einrückung... 😉

    Meiner Ansicht verlassen sich manche Leute viel zu oft auf Compileroptimierungen, was in einigen Fällen das Selber Überlegen eindämmt. Wenn ich weiss, dass ich ein riesiges Objekt habe, dann gehe ich nicht das Risiko ein, das bei jeder Iteration neu zu konstruieren. Zumal es gut sein kann, dass mein Compiler so was vielleicht optimiert, der des nächsten Users aber nicht mehr. Wie gesagt, grosse Objekte, lokale int s sind ein anderes Thema.

    Und auch das Argument mit dem Scope ist etwas fragwürdig. Klar, im Allgemeinen ist es vorteilhaft, Variablen so lokal wie möglich zu halten. Aber eben, im Allgemeinen. Und was spricht gegen so was? Da hat man das Objekt genauso lokal, stellt aber einmalige Konstruktion sicher.

    void Function()
    {
        // viel Code
        {
            GrosseKlasse Objekt;
            while (...)
            {
                // mach etwas mit Objekt
            }
        }
        // viel Code, der nichts von Objekt wissen darf.
    }
    

    Hier ging es ja ursprünglich um Zuweisung vs. Initialisierung. Wenn natürlich die Zuweisung annähernd so aufwändig wie die Initialisierung ist, kann man sich eine lokale Variable schon eher überlegen. Kommt halt auch wieder auf den Fall an, aber wie gesagt würde ich nicht auf eine massive Compiler-Optimierung hoffen, wenn ich durch eine Deklaration ausserhalb der Schleife nichts verliere.



  • pumuckl schrieb:

    asc schrieb:

    Es gab lange eine Fraktion die meinte alle Variablen müssen am Anfang eines Blockes (z.B. Funktion) deklariert werden

    Die Fraktion hatte da auch gute Gründe für:...

    Die Fraktion hatte tatsächlich gute Gründe in der Anfangszeit, nur das die Gründe (u.a. durch die Weiterentwicklung von Compiler und Programmiertechniken) mit der Zeit weggefallen sind, und es dann tatsächlich nur noch "Das war schon immer so" war 😉

    Ähnlich wie einige C++ Entwickler jegliche Entwicklung verschlafen haben...

    cu André



  • asc schrieb:

    Es gab lange eine Fraktion die meinte alle Variablen müssen am Anfang eines Blockes (z.B. Funktion) deklariert werden

    Das ist nicht zu beanstanden, solange die Funktionen klein genug sind. Dann finde ich es sogar übersichtlicher.



  • audacia schrieb:

    asc schrieb:

    Es gab lange eine Fraktion die meinte alle Variablen müssen am Anfang eines Blockes (z.B. Funktion) deklariert werden

    Das ist nicht zu beanstanden, solange die Funktionen klein genug sind. Dann finde ich es sogar übersichtlicher.

    Und meine Erfahrung war damals eher, dass die Funktionen sehr lang waren (was die lange Variablenliste umso schlimmer machte 😉 ). Das war aber gar nicht so verkehrt, da man ohne IDE nicht mal eben per ComboBox oder speziellen Funktionen (goto implementation usw.) schnell zur gewünschten Funktion springen konnte. Ein reiner DOS-Texteditor war halt nicht so komfortabel. Dann lieber eine etwas größere Funktion, in der ich mich länger aufhalte, statt vieler kleiner Splitter, zwischen ich ständig umständlich hin- und herspringen muss. Das hat imho schon Sinn gemacht. Mittlerweile machen moderne IDEs viele kleine Funktionen - verteilt auf viele Dateien - bequem möglich.


Anmelden zum Antworten