Arbeitsweise / Speichernutzung / Performance

Status
Nicht offen für weitere Antworten.

RaoulDuke

Bekanntes Mitglied
Hallo,

ich hatte mal wieder eine Diskussion zum Thema Umgang mit Daten im Speicher und Trennung von Funktionalität und Darstellung.

Ich habe mich mit dem MVC Konzept beschäftigt, ein Buch über Struts gelesen und auch schon ein paar Kleinigkeiten mit Java und Struts realisiert. Die Trennung von Funktionslogik und Darstellung gefällt mir hier sehr gut. Meine Programme arbeiten prinzipiell immer so, dass über eine Action und Service Klassen Daten abgerufen, geschrieben, Ergebnissbeans erzeugt werden, etc. Ergebnissbeans werden dann halt an den View übergeben und per Struts Tagslib dargestellt.

Jetzt habe ich aber das Problem, dass Kollegen von mit der festen Überzeugung sind, dass man aus Gründen der Arbeitsspeicherschonung niemals mehr als eine Zeile aus einer Datenbank lesen sollte bevor man diese ausgibt. Wenn ich also z.B. eine Tabelle erzeugen will die 100 Zeilen hat, dann sollte ich diese nicht erst in eine Collection von Ergebnissbeans einlesen, sondern immer eine Zeile erzeugen, ausgeben und dann die nächste abrufen, erzeugen, etc...

Das Ganze hat ja schon auch irgendwie Sinn, aber ich wüsste nicht wie man das so in einem ordentlichen MVC Konzept realisiert krigt.

Ich persönlich finde die ganze Diskussion eigentlich total unsinnig, da es mich eigentlich nicht schert ob ich 10k mehr oder weniger in der Speicher lade, aber bei diversen Perl Programmierern hier kann ich mit solchen Konzepten keinen Blumentopf gewinnen. Ich weiss nur irgendwie nicht wie ich da am besten argumentieren soll, und daher wollte ich mal ganz gerne ein paar mehr Meinungen dazu hören.
 

foobar

Top Contributor
Also wenn du alle Beans auf einer Seite ausgeben willst, kannst du sie ruhig alle in den Speicher laden, aber wenn du nur 5 Beans anzeigen willst macht es keinen Sinn die komplette Tabelle zu laden.
Am schönsten ist sowas über Paging zu lösen. D.h. du lädst immer eine bestimmte Anzahl von Beans aus der DB und merkst dir die Position. Beim nächsten Request holst du dann die Beans ab dieser Position bis zur Position X. So kann der Benutzer z.b. durch eine Liste von Suchergebnissen navigieren.
Dem MVC ist es doch egal ob du eine Methode hast ladeAlleBeans oder ladeBeanMitDemWertFoo.
 

RaoulDuke

Bekanntes Mitglied
Natuerlich lade ich niemals mehr in den Speicher als nötig. Also wenn ich nur 5 Zeilen ausgeben will, dann lade ich auch nur genau 5 in den Speicher. Aber selbst das kann ich halt manchen Leuten nicht erklären, weil die sagen: Dann mach nen Select, ne Schleife über das Resultset, lese einen Datensatz, gib einen aus, das ganze 5 mal.

An solchen Punkten scheitert dann sofort jeder Versuch zu erklären warum ich eine Trennung von Logik und Darstellung und eine Objektorientierte Programmierweise für vorteilhaft halte. Dann heisst es nämlich sofort: "Ähh, OO, das is eh alles Speicherverschwendung, das sieht man ja an solchen Fällen."
 

foobar

Top Contributor
"Ähh, OO, das is eh alles Speicherverschwendung, das sieht man ja an solchen Fällen."
Geil !!

Ich verstehe was du meinst. Dennoch würde ich die Beans in eine Collection packen und dann später darüber iterieren. Wie groß ist denn die Anwendung? Wieviele Datensätze hat die Mastertabelle? Wenn du > 1 Million Datensätze hast würde ich mir etwas mehr Gedanken über Speicherverbrauch machen, aber in den meisten Fällen hat man nicht mehr als ein paar 10 000.
 

RaoulDuke

Bekanntes Mitglied
Es geht dabei meist um nicht sonderlich grosse Tabellen. Die Art so zu denken ist hier aber bei den meisten Kollegen einfach Prinzip und die machen das immer so (und wollen das so haben, weil sonst isses ja unsauber) egal ob sie 2 oder 1000 Zeilen (oder was auch immer für Daten) anzeigen wollen.

Es gibt ja im Normalfall auch niemand 1 Million Zeilen auf einer Webseite aus. Man gibt ja auf Webseiten normalerweise nur so viel Daten aus wie der Betracher auch sinnvoll verarbeiten kann. Also in Dimensionen von bis 100k vielleicht. Grössere Datenbestände würde man ja eh seitenweise abrufen, dann hat man ja mit jedem Abruf auch nur eine minimale Datenmenge.

Es ging bei meiner Frage weniger um eine spezielle Anwendung sondern ums Prinzip. Bei kleinen Scripten die nur mal eben schnell was ausprinten stört mich die ganze Sache ja auch nicht so. Wir haben aber auch die ein oder andere Webanwendung mit einer Hand voll Views die auch dann und wann mal erweitert werden soll.

Jetzt z.B. ging es darum das ein Kollege anfing eine Webanwendung zu entwickeln, bei der Abzusehen ist, dass es in einem Jahr, statt um die eine Tabelle die er jetzt auflistet, um eine ganze Menge mehr Views und Funktionen gehen wird. Und ich war etwas genervt, dass ich wieder so ein Projekt angehängt krige, wo mal eben ein einzelner Programmierer nen Block Perlcode schreibt, der in jeder 2. Zeile HTML ausprintet, wo andauert haufenweise if Abfragen entscheiden ob jetzt Spitze Klammern (ok, etwas übertrieben) auf oder zu gehen, etc ...

Darüber kam es halt zu der Diskussion, da ich meinte das man das mal besser Strukturieren sollte, was dann aber in oben genannten Problemen mündet. Ich bin jedenfalls der Meinung das man Programme lieber ordentlich strukturieren sollte, auch wenn man dazu im Extremfall mal 100k in den Speicher lädt.
 

SnooP

Top Contributor
Ist der Netzwerkoverhead und die Belastung der DB nicht wesentlich größer, wenn man 5mal nen Query an die DB schickt, als nur einen?
Ich hab mal gelernt, dass man die Queries so gestalten sollte, dass sie genau das wiedergeben, was man haben möchte...
 

RaoulDuke

Bekanntes Mitglied
SnooP hat gesagt.:
Ist der Netzwerkoverhead und die Belastung der DB nicht wesentlich größer, wenn man 5mal nen Query an die DB schickt, als nur einen?
Ich hab mal gelernt, dass man die Queries so gestalten sollte, dass sie genau das wiedergeben, was man haben möchte...

Ich habe nicht gesagt das mehr als 1 Query gemacht wird.

Bei dem was ich beschrieben habe wird 1 Query gemacht, eine Zeile dem Ergebniss entnommen, verarbeitet, ausgegeben, nächste Zeile entnommen, verarbeitet ausgebeben, usw. Am Ende halt alles geschlossen.

Unter Perl wäre das halt so ähnlich:


Code:
$sth = $dbh->prepare($SQL);
$sth->execute();
while (@row = $sth->fetchrow_array) {
    # Verarbeiten, Ausgeben, etc
}
$sth->finish();

So in etwa kann ich das ja in Java auch machen. Query ausführen, Resultset abholen und iterieren. Und halt während des Iterierens gleich Ausgabe erzeugen und die Zeile nicht weiter speichern.
 

Reinski

Mitglied
Also meiner Ansicht nach ist das das typische Dilemma in das man kommt, je höher die eingesetzten Programmiersprachen stehen. Übertrieben ausgedrückt:
Wenn man Effizienz (Speicherbedarf und Performance) optimieren möchte, müsste man Assembler programmieren. Dass darunter der Komfort und die Fehlersicherheit leiden, braucht wohl nicht erwähnt zu werden.
Um optimalen Komfort und Sicherheit (insbes. bei größeren Projektteams) zu erhalten, greift man auf höhere Sprachen und Konzepte wie Libraries zurück. Dadurch erhöht sich aber der Overhead.
In deinem Fall scheint mir die unterschiedlichen Prioritäten zwischen dir und deinen Kollegen das Problem zu sein und durch die strikte Trennung der Ebenen wie im MVC Konzept lässt sich das meiner Ansicht nach auch nicht vermeiden.

In meinen Anwendungen mache ich es deshalb an Stellen wo dieses Problem auftritt so, dass die Präsentationsebene eine Methoden-Referenz (quasi Rücksprungadresse) an die Datenebene übergibt, über welche letztere einzelne Datenzeilen zur Formatierung und Darstellung an die Präsentation übergeben kann.
Dadurch entsteht zwar eine gewisse 'Verzahnung' von Präsentations- und Datenebene, aber letztere kann so die volle Performance entwickeln und trotzdem ist die Trennung der Bereiche bei der Entwicklung gewahrt.

Aber ich arbeite ja auch weitgehend alleine und muss keine Kollegen für das Konzept gewinnen... ;-)
Gruß!

reinski
 

Murray

Top Contributor
RaoulDuke hat gesagt.:
So in etwa kann ich das ja in Java auch machen. Query ausführen, Resultset abholen und iterieren. Und halt während des Iterierens gleich Ausgabe erzeugen und die Zeile nicht weiter speichern.

Du musst die Ausgabe ja nicht innerhalb der Schleife erzeugen, denn der Code gehört ja wirklich zum View. Aber Du kannst ja aus der Schleife heraus bei jeden Satz die Instanz triggern, die eigentlich zuständig ist. Dafür bietet sich das Observer/Observable-Pattern an:


Code:
public class Model {
  private Observable obsRecordProduced = new Observable();

  public Observable getRecordProduced() {
     return obsRecordProduced;
  }

  public void doQuery() {

     ResultSet rs = ... ;

     while (rs.next()) {
 
         MyRecordType myRecord = new MyRecord();
         /* jetzt Daten aus row übertragen*/
         obsRecordProduced.notifyObservers( myRecord);
     }
  }
}


public class View implements Observer {

   public void update( Observable o, Object arg) {
       MyRecordType myRecord = (MyRecordType)arg;
       /* jetzt Ausgabe erzeugen */
   }
}

public class Ctrl {
   private View view;
   private Model model;

   public Ctrl() {

       view = new View();
       model = new Model();

      //--- Verbindung herstellen:
     model.getRecordProduced().addObserver( view);



   }
}

Ist jetzt natürlich extrem vereinfacht, aber ich hoffe, das Prinzip wird trotzdem klar.
 

RaoulDuke

Bekanntes Mitglied
Murray hat gesagt.:
Ist jetzt natürlich extrem vereinfacht, aber ich hoffe, das Prinzip wird trotzdem klar.

Ja, das Prinzip leuchete ein. Ich kann mir nur irgendwie gerade nicht so richtig vorstellen wie sich das mit nem JSP View verwirklichen lassen würde. Man müsste irgendwie ein Observer Objekt haben das sich an den Out Stream klemmt und dann halt die Zeilen ausgibt oder so.

Ich glaube so ein Aufwand macht doch echt erst Sinn wenn man wirklich viele Daten liefern will und nicht nur ein paar KB.
 

Murray

Top Contributor
Klar; ob sich der Aufwand lohnt, hängt natürlich von den Datenvolumina ab. Ich würde nur die Aussage nicht unwidersprochen stehenlassen wollen, dass das MVC-Prinzip die Zwischenspeicherung der Daten zwingend erfordert, bzw. dass diese redundante Zwischenspeicherung ein notwendiges Übel beim Einsatz der OOP ist
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Wie kann ich mir die Arbeitsweise des Arbeitsspeichers vorstellen? Java Basics - Anfänger-Themen 9
O HashTable kann ohne Performance-Verlust in Multithreaded-Anwendungen eingesetzt werden. Java Basics - Anfänger-Themen 6
N Java-Performance messen Java Basics - Anfänger-Themen 1
B Performance-Vergleich mit C++ Java Basics - Anfänger-Themen 55
P Priority Queue Performance Java Basics - Anfänger-Themen 3
P Performance Array und Liste Java Basics - Anfänger-Themen 13
S Performance von byte[], short[], int[]..? Java Basics - Anfänger-Themen 24
I Erste Schritte Resource Bundle - Alles in einem File oder mehrere? => Faktor Performance Java Basics - Anfänger-Themen 2
E Hilfe zur Performance Verbesserung gesucht Java Basics - Anfänger-Themen 1
G Performance - höhere Anzahl Swing Elemente Java Basics - Anfänger-Themen 5
S Performance-/Stress Test für Webanwendung Java Basics - Anfänger-Themen 2
R Datei kopieren: Performance erhöhen Java Basics - Anfänger-Themen 10
S Wie performance lastig sind rekursionen Java Basics - Anfänger-Themen 13
N Bessere Performance durch final: wann denn überhaupt? Java Basics - Anfänger-Themen 28
J Softwaresynthesizer Performance? Java Basics - Anfänger-Themen 11
I Anzahl einer Liste (Performance) Java Basics - Anfänger-Themen 2
J Performance Vergleich von if-Abfragen mit mehreren Bedingungen Java Basics - Anfänger-Themen 9
S Performance HashMap<=>Array Java Basics - Anfänger-Themen 17
J Arrays erweitern - Performance vs Speicherverbrauch Java Basics - Anfänger-Themen 6
M Einträge in Dateien zählen - Performance-Problem Java Basics - Anfänger-Themen 10
S unterschied in performance Java Basics - Anfänger-Themen 4
hdi Worst-Performance-Award für Arbeiten mit ListModel Java Basics - Anfänger-Themen 7
hdi Performance Frage (Threads,Swing) Java Basics - Anfänger-Themen 4
V Performance Lesen und Schreiben aus/in Streams Java Basics - Anfänger-Themen 4
C große Matrizen, Performance, (Pointer?) Java Basics - Anfänger-Themen 6
G import .; - Speicherauslastung, Performance Java Basics - Anfänger-Themen 14
G Performance Java Basics - Anfänger-Themen 18
C Performance IO vs. NIO Java Basics - Anfänger-Themen 5
S dynamic arrays/ performance Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben