Datentypen Map effizient mit eigenem Key

S

Spacerat

Gast
Noch mal zum Thema immutable Keys... Die Keys sollen ja die DB-Abfragen beinhalten. Andere DB-Abfragen haben andere Resultate zur Folge. Ferner folgt daraus, dass veränderte DB-Abfragen nebst ihren Resultaten ohnehin neu in den Cache aufgenommen werden müssen. Das einzige, was sich an dem Schlüssel ändert wäre der Usecount bzw. der Zeitpunkt, an dem die Abfrage zum letzten mal stattfand. Diese Werte sind aber weder für "equals()" und "hashCode() noch für "compareTo()" relevant und können dort ignoriert werden. Den Rest der Schlüsselklasse kann man deswegen immutable gestalten, das ist definitiv um einiges performanter, weil das ständige Rehashing entfällt. "hashCode()" selbst könnte man dann z.B. mit 32-Bit RSA oder CRC32 per Objektserialisierung implementieren, der Hashcode wäre ja dann final.
BTW: Betrifft den oben genannten Begriff Usecount...
Als gute Idee hat sich bereits folgendes ergeben. Die Abfrage erhält bei ihrer ersten Verwendung einen Zeitstempel und einen Usecount von 1. bei jeder erneuten Verwendung inkrementiert man den Usecount. Mit einer Formel wie [c]currentTime - timeStamp <= useCount * minTimeToCache[/c] kann man so aufgrund der Häufigkeit der Verwendung entscheiden, wann die Abfrage aus dem Cache entfernt werden soll. Höhere UseCounts bedeuten längere Cache-Zeiten. Natürlich kann man die Formel auch so umstellen, dass man den Zeitstempel lediglich um minTimeToCache pro Verwendung erhöhen kann.
 

Dragonfire

Bekanntes Mitglied
Noch mal zum Thema immutable Keys... Die Keys sollen ja die DB-Abfragen beinhalten. Andere DB-Abfragen haben andere Resultate zur Folge. Ferner folgt daraus, dass veränderte DB-Abfragen nebst ihren Resultaten ohnehin neu in den Cache aufgenommen werden müssen. Das einzige, was sich an dem Schlüssel ändert wäre der Usecount bzw. der Zeitpunkt, an dem die Abfrage zum letzten mal stattfand. Diese Werte sind aber weder für "equals()" und "hashCode() noch für "compareTo()" relevant und können dort ignoriert werden. Den Rest der Schlüsselklasse kann man deswegen immutable gestalten, das ist definitiv um einiges performanter, weil das ständige Rehashing entfällt. "hashCode()" selbst könnte man dann z.B. mit 32-Bit RSA oder CRC32 per Objektserialisierung implementieren, der Hashcode wäre ja dann final.
BTW: Betrifft den oben genannten Begriff Usecount...
Als gute Idee hat sich bereits folgendes ergeben. Die Abfrage erhält bei ihrer ersten Verwendung einen Zeitstempel und einen Usecount von 1. bei jeder erneuten Verwendung inkrementiert man den Usecount. Mit einer Formel wie [c]currentTime - timeStamp <= useCount * minTimeToCache[/c] kann man so aufgrund der Häufigkeit der Verwendung entscheiden, wann die Abfrage aus dem Cache entfernt werden soll. Höhere UseCounts bedeuten längere Cache-Zeiten. Natürlich kann man die Formel auch so umstellen, dass man den Zeitstempel lediglich um minTimeToCache pro Verwendung erhöhen kann.

Das mit den final Feldern ist eine gute Idee und wird gleich mal getestet ;)
 

bERt0r

Top Contributor
Also ich kann dir sagen warum die DB bei dir so lahmt: Dein DB Manager ist Müll. Du machst ja bei jedem Update/Insert/irgendwas ein System.out.println. Das bremst SO enorm, wenn du das bei deinem HashTable auch machen würdest, lägst du in der gleichen zZ
 

Dragonfire

Bekanntes Mitglied
Also ich kann dir sagen warum die DB bei dir so lahmt: Dein DB Manager ist Müll. Du machst ja bei jedem Update/Insert/irgendwas ein System.out.println. Das bremst SO enorm, wenn du das bei deinem HashTable auch machen würdest, lägst du in der gleichen zZ

Nimm die Ausgabe raus,
oder pack sie bei der HashMap rein,
am besten beides mal ausprobieren ...
dann siehst du, dass dies ein unwichtiger Faktor ist ;)

Das Netzwerk ist einfach der Flaschenhals,
selbst lokal, ein L2 Cache, wie der RAM ist einfach
schneller, alleine weil er näher am Prozessor ist ...
 

bERt0r

Top Contributor
Aber es ist einfach nicht sinnvoll sich über Performance und Caching gedanken zu machen, wenn der Code des DB Controllers dermaßen ineffizient ist. Und ich muss dir hier ja nichts beweisen, du bist der mit dem Performaceproblem
 

bERt0r

Top Contributor
Ich kann dir sagen was du falsch machst:
  • Du bastelst bei jeder Abfrage einen neuen String zusammen.
  • Du schliesst deine Statements nicht.
  • Du erledigst alles über eine einzelne Connection.
  • Du machst mehrere System.out.printlns bei jeder Abfrage.
Nochdazu ist deine Konstruktion etwas unübersichtlich zu durchblicken. Normalerweise hat man z.B für ein Insert in eine Tabelle eine Funktion, in der steht der nicht veränderbare sql String fürs Prepared Statement z.B "INSERT INTO emp (vorname,nachname) VALUES(?,?)". Ohne zusammenbauen und ohne weiterreichen in irgendeine fastInsert Funktion.
 

fastjack

Top Contributor
Kurze Frage, kurze Antwort ;)

Wenn Du viele Key-Objekte erzeugst und das vermeiden willst, bist Du mit einem Pool sehr gut bedient. Zur Vereinfachung kannst Du Dir zusätzlich noch Factory-Klassen/Methoden schreiben, die die Keys zurückgeben, fertig.
 

fastjack

Top Contributor
Naja wahrscheinlich Reduzierung von Objekterzeugungen oder nicht? Es macht schon einen Unterschied, ob ich für (1,2,3, "a") jeweils n- XXXKey's erzeuge, oder nur einmal, und das Teil dann poole/share.
 

Dragonfire

Bekanntes Mitglied
Ich kann dir sagen was du falsch machst:
  • Du bastelst bei jeder Abfrage einen neuen String zusammen.
  • Du schliesst deine Statements nicht.
  • Du erledigst alles über eine einzelne Connection.
  • Du machst mehrere System.out.printlns bei jeder Abfrage.
Nochdazu ist deine Konstruktion etwas unübersichtlich zu durchblicken. Normalerweise hat man z.B für ein Insert in eine Tabelle eine Funktion, in der steht der nicht veränderbare sql String fürs Prepared Statement z.B "INSERT INTO emp (vorname,nachname) VALUES(?,?)". Ohne zusammenbauen und ohne weiterreichen in irgendeine fastInsert Funktion.


1. Hast du Recht, aber aus irgendeinen Grund optimiert das JAVA weg ...
zumindes bei mir^^
Ist ja auch eine Quick und Dirty Klasse, sonst arbeite ich immer mit PreparedStatments ...
2. Mist, da hast du Recht xD
3. Willst du für jede Abfrage eine eigene Connection machen? Wie sollte man es denn machen?
4. Hatte die auch mal rausgenommen, ändert nichts, hatte ich aber schon geschrieben ...

Naja wahrscheinlich Reduzierung von Objekterzeugungen oder nicht? Es macht schon einen Unterschied, ob ich für (1,2,3, "a") jeweils n- XXXKey's erzeuge, oder nur einmal, und das Teil dann poole/share.

Korrekt^^
So hätte ich es dann auch bei den Connections gemacht ...
 

fastjack

Top Contributor
1. Hast du Recht, aber aus irgendeinen Grund optimiert das JAVA weg ...
zumindes bei mir^^

Glück gehabt bis jetzt...

Ist ja auch eine Quick und Dirty Klasse, sonst arbeite ich immer mit PreparedStatments ...

quick and dirty ist, was es ist. Dann mach das, was Du auch sonst immer machst.

2. Mist, da hast du Recht xD
3. Willst du für jede Abfrage eine eigene Connection machen? Wie sollte man es denn machen?

Wenn es stört, dann benutze einfach mehrere Connections. Die mußt Du dann aber auch verwalten, d.h.Öffnen/Schliessen etc. ConnectionPool vielleicht?
 

bERt0r

Top Contributor
Naja wahrscheinlich Reduzierung von Objekterzeugungen oder nicht? Es macht schon einen Unterschied, ob ich für (1,2,3, "a") jeweils n- XXXKey's erzeuge, oder nur einmal, und das Teil dann poole/share.

Soso, mal angenommen der Benutzer gibt dir ein Key 1,2,3. Dann bist du so schlau und speicherst jetzt 123 in deinen KeyPool. Jetzt kommt von irgendwoher noch eine Anfrage nach dem Wert für den Key 123. Jetzt schaust du also im Keypool nach, ob 123 drin ist und holst den string da raus oder wie? Oder meinst du gleich das Caching das dragonfire mit seiner Hashmap ja erreichen will.
Leider füllt sich deine Hashmap irgendwann und ist dann genausogroß wie die Datenbank. Das heisst dann brauchst einen Mechanismus, der die gecachten Daten wieder vergisst.
Warum nicht gleich alles einlesen?
Wenn nach der Optimierung bei der DB Anbindung wirklich noch Bedarf an mehr Performance ist, kann man ja auf Caching zurückgreifen. Ich hab glaub ich einen Link zu so einem Projekt gepostet, bei dem ich zumindest denke dass sich die Entwickler mehr Überlegungen und Wissen hineingesteckt haben, als du oder ich hier. Du benutzt schließlich auch die vorgefertigte Hashmap und keine selbst zusammengehackte.

Zu 1. Nein, Java optimiert das nicht weg. Konnte ich selbst bei einer Anwendung mit ein paar Millionen Inserts erfahren, wo die Laufzeit unter anderem durch effizientens Erstellen von SQL Code von 45 Minuten auf 2 reduziert wurde.
3. Google mal ConnectionPool. Besonders wenn du, wie hier angedeutet, viele Parallele Zugriffe auf deinen Server und deine Db hast, ist eine größtmögliche Parallelisierung des DB Zugriffs natürlich enorm wichtig. Datenbanken sind ja auf Mehrbenutzerbetrieb ausgerichtet.
 
Zuletzt bearbeitet:

fastjack

Top Contributor
Soso, mal angenommen der Benutzer gibt dir ein Key 1,2,3. Dann bist du so schlau und speicherst jetzt 123 in deinen KeyPool. Jetzt kommt von irgendwoher noch eine Anfrage nach dem Wert für den Key 123. Jetzt schaust du also im Keypool nach, ob 123 drin ist und holst den string da raus oder wie?
warum nicht?

Leider füllt sich deine Hashmap irgendwann und ist dann genausogroß wie die Datenbank. Das heisst dann brauchst einen Mechanismus, der die gecachten Daten wieder vergisst.

Den brauchst er sowieso, um seinen Cache aktuell zu halten.

Warum nicht gleich alles einlesen?

Die ganze DB einlesen? Weis nicht... Außerdem hat er beschrieben, daß er nicht nur DB's als Datenquellen hat.

Ich hab glaub ich einen Link zu so einem Projekt gepostet, bei dem ich zumindest denke dass sich die Entwickler mehr Überlegungen und Wissen hineingesteckt haben, als du oder ich hier. Du benutzt schließlich auch die vorgefertigte Hashmap und keine selbst zusammengehackte.

Das überzeugt mich jetzt irgendwie nicht so... Er hat halt eine Lösung genommen, die für ihn 100% passt, was garantiert bei vielen Fertiglösungen nicht so sein wird.
 

bERt0r

Top Contributor
Was bringt dir der Pool? Du hältst dann alle bereits verwendeten Keys in einer Collection. Die neuen Keys die reinkommen sind aber wieder seperate Objekte, also speicherst du dadurch alles doppelt.
Das ist so als hättest du ein Telefonbuch - deine DB - und ein Buch, in dem alle Namen nochmal drinstehen - deinen Keypool. Wenn du jetzt die Telefonnummer von Max Mustermann suchst, siehst du erst in deinem Namensbuch nach ob er da drinsteht und dann im Telefonbuch??? Das ist doch unsinn!
Und nein, diesen Mechanismus hat er eben nicht, zumindest nicht gepostet.
 
Zuletzt bearbeitet:
S

Spacerat

Gast
Hier stimme ich bERt0r definitiv zu. Die Keys des Cache wären die Statements, die Values halt die Resultate. Die Statements sind in einer Anwendung aber meistens recht zahlreich und obendrein auch noch verschieden. Sie deswegen zusätzlich noch in einem Pool zu halten macht wirklich absolut keinen Sinn. Aber für den Fall, es wird doch einer benötigt...
Java:
Set<Key> pool = MyMap.keySet();
bitteschön... ;)
 

fastjack

Top Contributor
Statements zu speichern bringt in diesem Fall aber nicht viel, da verschiedenste Datenquellen angebunden werden sollen (auch nicht SQL).
 

Dragonfire

Bekanntes Mitglied
Ich habe mich jetzt einfach für die HashMap entschieden und ohne KeyPool,
mit dem einem new muss ich halt leben^^
Das verwalten der Keys ist ein wenig "überdimensioniert" und wie beschrieben wurde,
erst nachzuschauen was der Key ist um dann in der Map den Wert zu finden ....
dazu passt die Anwendung nicht ...
Hatte mal für jeden Thread einen eigenen "SuchKey" bereitgestellt,
die Performancesteigerung war gleich null, JAVA kann sowas anscheinende echt gut xD

Das Telefonbuch-Beispiel passt hier ganz gut ...

Ich habe immer wieder die gleichen Anfragen nach Nummern aus einer GROSSEN Menge,
also bastel ich mir ein kleines eigenes Telefonbuch,
wo das nachschauen schneller geht.

Wenn ich es dort nicht finde,
schaue ich im großen Telefonbuch nach oder rufe die Auskunft an xD

PS.: Kennt sich einer zufällig mit JAVA Persistence aus?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Große Datenmengen effizient programmieren Allgemeine Java-Themen 51
K Große JSON-Dateien schnell und effizient verarbeiten Allgemeine Java-Themen 16
T Daten effizient verwalten Allgemeine Java-Themen 4
H Sehr viele Threads effizient Verwalten Allgemeine Java-Themen 13
T [RXTX] GPS-Maus (Comport) effizient auslesen Allgemeine Java-Themen 6
B Daten effizient ein- und auslagern Allgemeine Java-Themen 7
S Algorithmus Problem. Rechtecke effizient auf Spielfeld anordnen. Allgemeine Java-Themen 7
Ark Arkussinus effizient berechnen Allgemeine Java-Themen 12
T WeakHashMap: Wie "null" effizient abfangen? Allgemeine Java-Themen 5
J Datei Inhalt vergleichen (schnell & effizient!) Allgemeine Java-Themen 10
Zrebna Zuverlässiges Automatisiertes Testen im eigenem Software-Unternehmen aufsetzen - How to? Allgemeine Java-Themen 12
C Frage zu eigenem TableCellRenderer Allgemeine Java-Themen 11
MiMa Log4j in Dateien mit eigenem Namen schreiben Allgemeine Java-Themen 3
D JAVA Basiertes Spiel aus dem Internet in eigenem Client laden Allgemeine Java-Themen 3
N ArrayList in eigenem Object nicht richtig serialisierbar Allgemeine Java-Themen 14
T AES-Verschlüsselung mit eigenem 256 Bit Schlüssel Allgemeine Java-Themen 12
M Über Liste verschiendene JComponents mit eigenem implementierten Interface ansprechen Allgemeine Java-Themen 7
K Programm startet nur auf eigenem Rechner??? Allgemeine Java-Themen 6
DStrohma Jede node in JTree mit eigenem Icon Allgemeine Java-Themen 7
M Eigenem Dateiformat Icon zuweisen Allgemeine Java-Themen 6
S Problem mit eigenem DatenTyp. HILFE!!! Allgemeine Java-Themen 4
M jdbc treiber (h2) mit eigenem ClassLoader laden Allgemeine Java-Themen 4
D Abstruse Probleme mit eigenem replace Algorithmus Allgemeine Java-Themen 11
R HashSet mit eigenem Objekt als Key Allgemeine Java-Themen 10
A jpeg Files mit eigenem Programm öffnen Allgemeine Java-Themen 4
F Probleme mit eigenem Plugin-System Allgemeine Java-Themen 3
H externe JARs in eigenem Programm-Jar einbinden. Allgemeine Java-Themen 5
F "source not found" in eigenem Projekt mit eigenen Allgemeine Java-Themen 2
W Externes Programm beenden mit eigenem Programm beenden Allgemeine Java-Themen 7
D Programm mit eigenem ClassLoader funktioniert nicht Allgemeine Java-Themen 12
K KeyEvent in eigenem Component geht nicht Allgemeine Java-Themen 3
R Problem beim speichern von eigenem objekt Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben