Wie lazy evaluation bei Abhängigkeiten



  • Moin!

    Angenommen ich habe folgende Klasse:

    class MyClass {
    public:
        double getA();
        int getB();
        double getC();
    
    private:
        double a,c;
        int b;
    };
    

    Jetzt will ich a b und c aber nur bei Bedarf berechnen, das Ergebnis dann auch intern speichern und beim nächsten mal nicht wieder neu berechnen.

    Problem: Stellenweise existieren abhängigkeiten. Beispiel:

    b = 17+3;
    c = b / 2.0;
    a = b-c;
    

    b könnte ich also bei Bedarf direkt berechnen. Bei c wiederum müsste ich ja wissen, ob ich b schonmal berechnet habe (boolesche Variable?). Wie löst man das am elegantesten? Ich kann zu Beginn ja nicht sagen b = -1, weil im realen Szenario der gesamte Wertebereich des Integer verwendet wird.



  • Zeiger verwenden. Zeiger ist 0, wenn der Wert noch nicht berechnet wurde, sonst zeigt er auf den Wert.
    Im Allgemeinen macht sowas aber ehrlich gesagt kaum Sinn. Wenn das tatsächlich nur einfache Additionen/Divisionen sind ist jedesmal neu berechnen wohl schneller - und leichter. Stichwort premature optimization.



  • Verwende einen bool oder boost::optional (läuft meines Wissens auf das gleiche raus).
    EDIT: Wenn auch Speicher lazy verwendet werden soll, bietet sich natürlich auch ein pointer an, aber dynamischer Speicher ist bei einzelnen ints oder doubles sehr wahrscheinlich langsamer und verbraucht im Endeffekt mehr Speicher als ein boost::optional.


  • Mod

    Hast du dies mal versucht?
    Google: lazy evaluation c++
    Da werden gute und allgemeine Verfahren erklärt.



  • 👍
    Boost.Optional ist eine Lib die mMn. viel mehr Aufmerksamkeit verdient als sie erhält.
    Vielleicht wäre ein anderer Name besser gewesen, z.B. nullable .

    Und ja, für das hier beschriebene Beispiel macht das alles keinen Sinn, da die Berechnung so ultimativ billig ist, dass sämtliche Optimierungsversuche mit Lazy-Evaluation zum Scheitern verurteilt sind.

    Für aufwendigere Berechnungen kann es allerdings Sinn machen.
    Und dann sind boost::optional oder boost::scoped_ptr/std::unique_ptr gute Möglichkeiten. Je nach sizeof(T) .



  • hustbaer schrieb:

    👍
    Boost.Optional ist eine Lib die mMn. viel mehr Aufmerksamkeit verdient als sie erhält.
    Vielleicht wäre ein anderer Name besser gewesen, z.B. nullable .

    Und ja, für das hier beschriebene Beispiel macht das alles keinen Sinn, da die Berechnung so ultimativ billig ist, dass sämtliche Optimierungsversuche mit Lazy-Evaluation zum Scheitern verurteilt sind.

    Für aufwendigere Berechnungen kann es allerdings Sinn machen.
    Und dann sind boost::optional oder boost::scoped_ptr/std::unique_ptr gute Möglichkeiten. Je nach sizeof(T) .

    Ich finde, es hängt nicht nur von der Größe von T ab, sondern auch, wie oft eine Klasse instanziiert wird. Nur weil MyClass billige Berechnungen enthält, summiert sich das am Ende trotzdem auf, wenn z.B. alle 20 ms zwischen 1400 und 2000 Objekte von MyClass angelegt werden, von denen aber anschließend 1000 verworfen werden und man die Berechnungen nur für die verbleibenden objekte braucht


Anmelden zum Antworten