Referenz im Konstruktor übergeben oder bei jeder Funktion?



  • Hallo Leute, ich programmiere gerade an einem Spiel mit mehreren Levels usw. 😉
    Nun habe ich manche Funktionen in Tochterlassen, die ich pro Frame einmal aufrufe und denen ich bei jedem Durchlauf eine Referenz auf das GLEICHE Objekt der Mutterklasse übergebe. Lohnt es sich ( der Leistung wegen, die ich sparen möchte), die Referenz an den Konstruktor der Tochterklasse zu übergeben und dort eine neue Referenz für die Tochterklasse anzulegen(die Referenz zu "kopieren")? Oder macht es garkeinen unterschied ob ich die Referenz bei jedem Funktionsaufruf übergebe? 😉

    Danke im voraus für eure Hilfe 🙂



  • Jeder zusätzliche Parameter, der an eine Funktion übergeben wird macht deren Aufruf langsamer, da er mit Push erst auf den Stack draufgelegt werden muss und dann mit Pop runter genommen wird.

    Ich denke mal du hast sowas hier vor:

    class LevelItem
    {
       Level * level;
    
       LevelItem(Level * level)
       {
          this.level = level;
       }
    
       void Move()
       {
          this.level.CollisionsAbfrageMitLevel(this);
       }
    }
    

    Ein Arbeitskollege hat mich deswegen schon gerügt, weil ich den gleichen Ansatz wie du hatte. Dein Ansatz führt dazu, dass dein LevelItem immer größer anwächst und komplexer wird. Jede Klasse sollte immer nur genau eine Aufgabe machen. Beispiel: LevelItem-Zeichen, LevelItem bewegen, LevelItem-Data-Klasse. Jedes davon ist eine eigene Klasse.



  • Danke für die schnelle Antowort 😉 Also wenn ich sowieso immer die gleiche Referenz übergebe, dann nicht bei jedem Funktionsaufruf, sondern um Konstruktor und dort kopiere ich die Adresse der REferenz in eine private Referenz und muss somit der Funktion in der externen Klasse keine Referenz mehr übergeben 😉


  • Mod

    das kommt auf die situation an, klassen aufzublaehen mit immer denselben pointern kann langsammer sein als die parameter zu uebergeben.



  • Komplett irrelevant. In den inneren Schleifen wird die Rechenzeit verbraten. Ob's nu strcpy(u_foo oder strcpy(m_foo wird, macht den Kohl nicht fett.



  • @volkard
    Es ändert sich ja nicht nur die Parameterübergabe. Die nebenbei auch nicht immer wegoptimiert werden kann. Und nicht jede Funktion die Parameter hat tut auch viel.

    Es ändert sich auch das Speicherlayout. Und die Chancen des Optimizers zu wissen dass "u_foo" und "u_foo.x" und "u_foo.y" etc. konstant über die u.U. performancekritische enge Schleife sind.

    Das alles einfach mit "komplett irrelevant" abzutun halte ich für komplett falsch.



  • volkard schrieb:

    Komplett irrelevant. In den inneren Schleifen wird die Rechenzeit verbraten. Ob's nu strcpy(u_foo oder strcpy(m_foo wird, macht den Kohl nicht fett.

    die gestiegenen cache misses wegen den groesseren objekten koennen mehr kosten als die abarbeitung innerhalb der funktion.

    class OBB
    {
    _m128 Center;
    _m128 Extend;
    };
    

    vs

    class Rect
    {
    _m128 Center;
    _m128 Extend;
    CollisionManagerMutter* ptr;
    };
    

    nicht nur wegen der reinen groesser, sondern auch weil du nun cacheline crossing hast.

    deswegen wuerde ich nicht generalisiert einem anfaenger beibringen dass der eine weg besser als der andere ist, schon garnicht "komplett irrelevant". das wird verinnerlicht ohne die gruende zu verstehen und am ende gibt es dickkoepfige besserwisser "weil mir das jemand im forum gesagt hat".


Log in to reply