Hi,
ich habe ein kleines Performance-Problem und suche nach Lösungen.
Momentan habe noch ein Webprojekt mit Servlets und JSP nach dem MVC-Prinzip.
Eines meiner Klassen ist Flat.java.
In Flat befindet sich alles weitere an Objekten was so zu einer Flat gehört, u. a. Kaufdatum, Mieter, Kaufpreis, ...
Für Auswertungen habe ich bisher "on-the-fly" den Profit dieser Wohnung berechnet. Also auf der einen Seite alle Einnahmen errechnet, alle Ausgaben und diese voneinander subtrahiert. Das selbe gabs dann noch mal Methoden die Ergebnisse kumuliert zurückgeliefert haben.
Wie gesagt, bei jedem Aufruf einer bestimmten JSP-Seite geschah das vollständig erneut, ich habe keine Ergebnisse zwischengespeichert. Eine gängige Methode sah z. B. so aus:
Damit hatte ich keine Performance-Probleme und im Prinzip war alles gut. Der Parameter yearOfFunding bzw. years bezog sich jedoch nicht auf ein Kalenderjahr, sondern war einfach ein Zähler ab Kaufdatum der Wohnung.
Wenn z. B. am 01.07.2015 eine Wohnung erworben wurde, war yearOfFunding = 0 zwischen 01.07.2015 - 30.06.2016, =1 zwischen 01.07.2016 - 30.06.2017 usw.
Für Auswertungen auf Jahresebene war das nicht so schön, denn die ganzen Methoden rufe ich in einem Kontext auf: Gib mir mal den Profit für 2015, 2016 oder 2029 und zwar unabhängig davon wann die Wohnung gekauft wurde (gerade wenn man über mehrere Wohnungen iteriert ist das wichtig).
Also habe ich mir gedacht, bau ich das mal wie folgt um:
Von der Funktioniert ist das jetzt auch super, genau das was ich brauchte. Allerdings ist die Performance so schlecht, dass ich das nicht so lassen kann. Vor allem die set und get-Methoden, also sowas wie:
Fressen extrem viel Performance laut JProfiler.
Grundsätzlich handelt es sich bei all den Daten um Sachen die zwar sehr oft abgerufen werden, aber eher selten verändert.
Ich könnte jetzt natürlich die Ergebnisse der Teil komplexen Berechnungen abspeichern und nur neu berechnen lassen, wenn es ein Eingangsparameter für die Berechnung ändert. Das macht das System aber natürlich anfällig, insofern dass ich überall und ständig daran denken muss die Berechnung neu anzustoßen. Aus diesem Grund finde ich das eher nicht so gut.
Gibt es irgendwas in Richtung Caching, was mir die Arbeit erleichtern könnte oder habt ihr eine Idee? Oder sollte ich vielleicht die Methoden wieder umbauen und das Problem anders lösen?
Vielen Dank im Voraus für eure Hilfe
ich habe ein kleines Performance-Problem und suche nach Lösungen.
Momentan habe noch ein Webprojekt mit Servlets und JSP nach dem MVC-Prinzip.
Eines meiner Klassen ist Flat.java.
In Flat befindet sich alles weitere an Objekten was so zu einer Flat gehört, u. a. Kaufdatum, Mieter, Kaufpreis, ...
Für Auswertungen habe ich bisher "on-the-fly" den Profit dieser Wohnung berechnet. Also auf der einen Seite alle Einnahmen errechnet, alle Ausgaben und diese voneinander subtrahiert. Das selbe gabs dann noch mal Methoden die Ergebnisse kumuliert zurückgeliefert haben.
Wie gesagt, bei jedem Aufruf einer bestimmten JSP-Seite geschah das vollständig erneut, ich habe keine Ergebnisse zwischengespeichert. Eine gängige Methode sah z. B. so aus:
Code:
public double getAccumProfit(int years) {
double res = 0;
for(int i = 0; i <= years; i++){
res = res + getProfit(i);
}
return res;
}
public double getProfit(int yearOfFunding) {
return getRevenue(yearOfFunding) - getCosts(yearOfFunding) - getCostsTax(yearOfFunding);
}
Damit hatte ich keine Performance-Probleme und im Prinzip war alles gut. Der Parameter yearOfFunding bzw. years bezog sich jedoch nicht auf ein Kalenderjahr, sondern war einfach ein Zähler ab Kaufdatum der Wohnung.
Wenn z. B. am 01.07.2015 eine Wohnung erworben wurde, war yearOfFunding = 0 zwischen 01.07.2015 - 30.06.2016, =1 zwischen 01.07.2016 - 30.06.2017 usw.
Für Auswertungen auf Jahresebene war das nicht so schön, denn die ganzen Methoden rufe ich in einem Kontext auf: Gib mir mal den Profit für 2015, 2016 oder 2029 und zwar unabhängig davon wann die Wohnung gekauft wurde (gerade wenn man über mehrere Wohnungen iteriert ist das wichtig).
Also habe ich mir gedacht, bau ich das mal wie folgt um:
Code:
public double getAccumProfit(DateTime tilYear) {
double res = 0;
/*
* loops trough the calendar years
*/
for(DateTime year=getDateOfPurchase(); year.isBefore(tilYear.dayOfYear().withMaximumValue()); year=year.plusYears(1) ) {
res = res + getProfit(year);
}
return res;
}
public double getProfit(DateTime year) {
return getRevenue(year) - getCosts(year) - getCostsTax(year);
}
Von der Funktioniert ist das jetzt auch super, genau das was ich brauchte. Allerdings ist die Performance so schlecht, dass ich das nicht so lassen kann. Vor allem die set und get-Methoden, also sowas wie:
Code:
year.getYear() - getDateOfPurchase().getYear()
Fressen extrem viel Performance laut JProfiler.
Grundsätzlich handelt es sich bei all den Daten um Sachen die zwar sehr oft abgerufen werden, aber eher selten verändert.
Ich könnte jetzt natürlich die Ergebnisse der Teil komplexen Berechnungen abspeichern und nur neu berechnen lassen, wenn es ein Eingangsparameter für die Berechnung ändert. Das macht das System aber natürlich anfällig, insofern dass ich überall und ständig daran denken muss die Berechnung neu anzustoßen. Aus diesem Grund finde ich das eher nicht so gut.
Gibt es irgendwas in Richtung Caching, was mir die Arbeit erleichtern könnte oder habt ihr eine Idee? Oder sollte ich vielleicht die Methoden wieder umbauen und das Problem anders lösen?
Vielen Dank im Voraus für eure Hilfe