Statische Variablen um Parameteranzahl zu verringern?



  • Abend,

    ich habe einen Baum, dessen Konstruktor recht viele Argumente bekommt. Sagen wir mal er sieht so aus:

    Baum::Baum(type1 param1, type2 param2, ..., type8 param) {
       arbeite mit den Parametern ...
       children[0] = new Baum(param1, param2, ..., param8);
       children[1] = new Baum(param1, param2, ..., param8);
       ...
       children[6] = new Baum(param1, param2, ..., param8);
    }
    

    Man sieht der Ctor kriegt recht viele Parameter, rechnet dann mit diesen rum und erzeugt dann rekursiv die 6 Kinder - damit wird dann ein recht großer Baum aufgebaut.

    Mein "Problem": Jede Baum Instanz kriegt ja immer die selben Parameter übergeben, also sowohl die Wurzel als auch die Kinder der Kinder der Kinder usw. Das ist ja eigentlich eine Performance-Verschwendung, weil jedesmal wieder alle Parameter auf den Stack gepusht werden usw.
    Ich könnte das jetzt einfach umgehen, indem ich die Parameter als static Member in Baum aufnehme und dann VOR dem Erzeugen der Wurzel einfach alle Member setze:

    Baum::param1 = foo1;
    Baum::param2 = foo2;
    ...
    Baum* baum = new Baum(); // Erzeuge Wurzel. Params muss ich nun nie mehr übergeben
    // da ja nun jede Instanz die statischen Params teilt
    

    Das wäre jetzt effizient aber das Problem ist, dass das Design irgendwie schräg ist, dann die ganzen Parameter brauche ich wirklich nur bei der ERZEUGUNG (sprich im Konstruktor) des Baums, danach nicht mehr. Dennoch hätte der Baum dann konsistent die ganzen Params (als static Member gespeichert)

    Was meint ihr? Ist das mit den vielen Parametern ok oder soll ich sie statisch machen oder was ganz anderes?



  • schon mal gemessen, ob das bei deinem Programm die meiste Zeit verbraucht? Wahrscheinlich nur dann, wenn dein Programm aus nix anderem besteht.



  • Statiker schrieb:

    Man sieht der Ctor kriegt recht viele Parameter, rechnet dann mit diesen rum und erzeugt dann rekursiv die 6 Kinder - damit wird dann ein recht großer Baum aufgebaut.

    "Recht" ist gut, "unendlich" triffts eher. Hast du eine mögliche Endlosrekursion bedacht?

    Statiker schrieb:

    Was meint ihr? Ist das mit den vielen Parametern ok oder soll ich sie statisch machen oder was ganz anderes?

    Du kannst die Parameter natürlich auch statisch im Konstruktor machen (also lokal), sodass sie ausserhalb nicht sichtbar sind. Oder du deklarierst gleich lokale Stack-Variablen (ist vielleicht ungünstig bei tiefen Rekursionen).

    Aber meinst du nicht, das Design ist grundsätzlich ein wenig fragwürdig? Beispielsweise hat ein Baum nicht unbedingt wieder einen Baum als Kind, eher einen Knoten.



  • Nexus schrieb:

    Hast du eine mögliche Endlosrekursion bedacht?

    Sicher, der Code läuft ja bereits. Der gepostete Code ist ja nur ein Beispiel.

    Statiker schrieb:

    Du kannst die Parameter natürlich auch statisch im Konstruktor machen (also lokal), sodass sie ausserhalb nicht sichtbar sind.

    Aber dann muss ich sie doch dennoch immer wieder im Ctor übergeben?

    Statiker schrieb:

    Oder du deklarierst gleich lokale Stack-Variablen (ist vielleicht ungünstig bei tiefen Rekursionen).

    Was meinst du mit "lokalen Stack Variablen"?

    Statiker schrieb:

    Aber meinst du nicht, das Design ist grundsätzlich ein wenig merkwürdig? Ein Baum hat nicht unbedingt wieder einen Baum als Kind, eher einen Knoten.

    In der Tat hab ich mich beim schreiben des Beispielcodes oben vertan. Die Instanzen sind natürlich alles Knoten, also denkt euch statt Baum einfach BaumKnoten. 😃



  • Statiker schrieb:

    Aber dann muss ich sie doch dennoch immer wieder im Ctor übergeben?

    Nein. Du deklarierst sie als statische Variablen innerhalb einer Funktion:

    void Function()
    {
        static int i;
        // i kann hier immer verwendet werden, ist jedoch nur einmal im Speicher.
        // Nach Ende des Blocks bleibt i erhalten.
    }
    

    Statiker schrieb:

    Was meinst du mit "lokalen Stack Variablen"?

    Ganz normale Variablen, die lokal innerhalb eines Blocks deklariert werden. Diese werden auf dem Stack angelegt:

    void Function2()
    {
        int i;
        // i wird bei jedem Funktionsaufruf neu angelegt.
        // Beim Ende des Blocks wird i zerstört.
    }
    


  • Und wie setze ich in beiden Fällen die Variable i?



  • Wahrscheinlich so, wie man eine Variable normalerweise "setzt". 😉

    Bei den statischen Variablen musst du einfach beachten, dass sie höchstens einmal initialisiert werden, und zwar bei ihrem ersten Vorkommen. Danach wird die Deklaration übergangen.



  • Nexus schrieb:

    Wahrscheinlich so, wie man eine Variable normalerweise "setzt". 😉

    Das ist schon klar, aber wie soll das in meinem Fall helfen? Da sie ja lokal ist, muss ich sie ja doch wieder JEDESMAL im Ctor übergeben, also:

    BaumKnoten::BaumKnoten(type1 param1, ..., type8, param8) {
       static type1 param_1 = param1;
       ...
    }
    

    Ich seh da irgendwie keinen Sinn drinnen? 😕



  • Aha sorry, ich habe dich so verstanden, dass du die Argumente auch innerhalb des Konstruktors kennst (ohne Übergabe von aussen).

    Wenn es immer die gleichen Argumente sind, lohnen sich statische Variablen innerhalb der Klasse schon.

    Eventuell könnte man sich auch überlegen, diese in separate Klassen auszulagern (z.B. Singletons). Gerade wenn die Argumente konstant sind, kann sich eine separate "Datenbank" bewähren.



  • Nexus schrieb:

    Wenn es immer die gleichen Argumente sind, lohnen sich statische Variablen innerhalb der Klasse schon.

    Hm ja. Es ist halt schon blöd bei nem "großen" Baum tausende Mal Variablen aufn Stack zu pushen obwohl die übergebenen Werte für jeden BaumKnoten immer die gleichen sind. Andererseits finde ich es halt auch nicht sooo elegant die ganzen Parameter als static Member anzulegen (sprich so:

    class BaumKnoten {
    private:
       static type1 param1;
       static type2 param2;
       ...
    public:
       BaumKnoten();
    };
    

    ) da man die dann in der Deklaration der Klasse sieht und sich fragt "für was braucht die Klasse denn die Variablen"? Und ferner brauch ich die ganzen statischen Variablen NACH Erzeugung nie mehr - sie bleiben aber natürlich erhalten. Ich glaub ich werf ne Münze... ^^



  • Ja, lokale Stack-Variablen sind wahrscheinlich keine so gute Lösung, das habe ich aber schon von Anfang an erwähnt.

    Und extra für den Fall, dass dir die statischen Variablen nicht passen, habe ich in meiner letzten Antwort noch einen weiteren Vorschlag gegeben.


Log in to reply