Designfrage: Werte erst berechnen wenn notwendig
-
Angenommen ich habe folgende Klasse:
template<class T> class Statistics { public: // Kann die Reihenfolge u.U. ändern (z.B. bei median) Statistics(std::vector<T>& vecData) : m_refVecData(vecData) { } private: std::vector<T>& m_refVecData; };
Jetzt bietet die Klasse verschiedene Funktionen an:
inline double sum() const { return std::accumulate(m_refVecData.begin(), m_refVecData.end(), 0.0); }
Die Summe soll also erst berechnet werden, wenn sie auch wirklich gebraucht wird. Hier schon das erste Problem. Wenn jemand die Funktion zweimal aufruft, dann wird sie auch zweimal berechnet. Soll ich die Summe jetzt als member-variable speichern und dazu einen boolean, ob sie bereits berechnet wurde?
Das gleiche dann bei anderen Funktionen, die stellenweise auch voneinander abhängen:
inline double mean() const { return sum() / m_refVecData.size(); }
Wie würdet ihr das lösen?
-
Vlt. gar keine Klasse und alles in einzelne Template-Funktionen? Das kam mir noch in den Sinn
-
Designer32 schrieb:
Soll ich die Summe jetzt als member-variable speichern und dazu einen boolean, ob sie bereits berechnet wurde?
Das kann man durchausmachen, wenn Geschwindigkeit wichtiger als Speicherplatz ist. Aber nicht vergessen den boolean zu setzen, sobald sich Werte im Array aendern.
-
Jupp, eine freie Funktion ist hier sinnvoller:
double sum(std::vector<double> const & vecData) { return std::accumulate(vecData.begin(), vecData.end(), 0.0); }
-
Wenn schon denn schon
template <typename Range> constexpr auto sum(Range const& range) { using std::begin; using std::end; return std::accumulate(begin(range), end(range), typename std::iterator_traits<decltype(begin(range))>::value_type{}); }
-
Siehe auch hier: http://gameprogrammingpatterns.com/dirty-flag.html
-
Lazy initialization! In deinem Fall halt Lazy-Sum.