Performance einer Monte-Carlo-Simulation verbessern

haaron

Mitglied
Hallo!

Ich verwende ein selbst geschriebenes Java-Programm um eine Monte-Carlo-Simulation durchzuführen. Ohne jetzt ins Detail gehen zu wollen, geht es dabei um Folgendes: Es wird die Entwicklung eines System konstanter Größe N (Größenordnung einige tausend bis einstelliger Millionenbereich) simuliert. Es werden pro Simulation 100.000 Simulationsschritte durchgeführt, wobei sich ein Simulationsschritt auf ein durchgeführtes Ereignis pro Objekt im System (also N Ereignisse) bezieht. Vor jedem Ereignis wird mit konstanten Wahrscheinlichkeiten ausgewählt, welche Art von Ereignis durchgeführt werden soll, denn es existieren prinzipiell verschiedene Ereignisse. Diese haben aber alle gemeinsam, dass sie eines oder zwei Objekte des Systems auswählen und anhand des Aktuellen Zustands des Systems die Eigenschaften des ausgewählten Objekts verändern. Ich habe diese Simulation in mehreren Versionen implementiert und dabei festgestellt, dass die Simulation gleicher Systeme in den unterschiedlichen Implementierungen jeweils unterschiedlich lange braucht. Folgende Versionen habe ich implementiert:

- Eine "Basic-Version", die nicht flexibel angepasst werden kann, also nur genau eine Art von System simulieren kann, dadurch konnte ich mir jegliche Vererbungen etc. sparen. Ich habe hier keinerlei Getter/Setter verwendet, sondern einfach alle Felder als public deklariert.
- Eine Version, welche zwar nicht wesentlich flexibler ist, aber die Style(?)-Vorgaben befolgte, also beispielsweise Getter/Setter
- Eine flexible Version, hier wurde viel mit Vererbung gearbeitet, es sind neue Arten von Systemen definierbar, sowie neue Ereignisse, etc.

Nun ist diese flexible Version leider am unperformantesten. Prinzipiell sind die Unterschiede hier nicht extrem, aber der benötigte Zeitaufwand wächst mit Systemgröße linear und bei den "großen" Systemen mit einer Größe macht dann ein Faktor 4-5 schon einen Unterschied, wenn statt 24h eben 5 Tage benötigt werden. Nun kann mit den Angaben die ich hier bisher gemacht habe vermutlich noch keine Diagnose gestellt werden, deshalb wollte ich nachfragen, ob ihr allgemeine Tipps habt, auf was ich bei einer solchen Art von Simulation achten sollte. Wenn ihr gute Beiträge, Webseiten, etc. dazu kennt nehme ich das alles gerne! Ich bin aber euch mehr Anfänger, deshalb fehlt mir eben auch der Blick "hinter die Kulissen".

Damit vielleicht noch spezifischere Tipps gegeben werden können hier nochmal ein paar weitere Infos, ich erkläre es mal recht abstrakt, weil es sonst vielleicht noch komplizierter wird:

Jedes Ereignis kann angenommen oder abgelehnt werden. Dafür wird das Ereignis durchgeführt (Details dazu gleich) und anschließend eine Wahrscheinlichkeit berechnet dieses Ereignis anzunehmen oder abzulehnen, die entsprechende Wahrscheinlichkeit wird mit java.lang.Math.exp berechnet, das Argument der Funktion wird berechnet aus dem Zustand des Systems vor der Durchführung des Ereignissen und dem Zustand danach. Wird das Ereignis abgelehnt, dann wird das bereits durchgeführte Ereignis einfach wieder rückgängig gemacht (alle geänderten Variablen auf ihren Ausgangszustand gesetzt).

Nun zu den Ereignissen: Für jedes Ereignis existiert eine eigene Klasse, die von der Klasse AbstraktesEreignis erbt. In der abstrakten Klasse wird nur die Methode zur Berechnung der Wahrscheinlichkeit implementiert. Jedes Ereignis besitzt eine Methode perform() zur Durchführung. Es existiert zusätzlich eine Klasse, die sich um die Verwaltung der Ereignisse kümmert: Hier werden jeweils Objekte der Ereignisse gespeichert und hier erfolgt die Auswahl eines Ereignisses anhand der Ziehung der Zufallszahlen. Die Ereignisse verändern jeweils die Objekte des Systems, dafür besitzen sie entweder eine Referenz zum Array der Objekte (welcher ursprünglich der System-Klasse ist) oder eine eigene Version davon, in dem beispielsweise die Ereignisse nach einer bestimmten Eigenschaft der Objekte sortiert vorliegen.

Nun ist der Vorgang einfach folgender, dass jedes Mal im EreignisManager ein zufälliges Ereignis ausgewählt wird, es wird dessen perform()-Methode aufgerufen und in der Perform-Methode wird dann das Ereignis angenommen oder abgelehnt. In den Perform-Methoden werden dann beispielsweise auch noch weitere Zufallszahlen gezogen, es werden ArrayLists erstellt, Schleifen durchlaufen, if-Bedingungen geprüft, etc.

Und dazu noch eine etwas konkretere Frage: Ich verwende Beispielsweise ArrayLists, weil ich Objekte "sammeln" muss, die eine bestimmte Eigenschaft besitzen. Da mache ich mithilfe einer for-Schleife, in der mithilfe einer if-Bedingung einfach gefragt wird, ob die Eigenschaft erfüllt wird. Nun ist es eben so dass dadurch die Länge der ArrayList variieren kann, weshalb ich auch keinen Array verwende. Allerdings kann die Länge höchstens einen (konstanten) Maximalwert annehemen. Ist es dann beispielsweise performanter, einen Array zu erstellen, der Länge dieses Maximalwerts und dann später beim iterieren über diesen jeweils zu überprüfen ob das jeweilige Objekt null ist und dann die Schleife zu beenden?



Ich hoffe das alles gut verständlich ist und ich die wichtigsten Infos genannt habe. Ich würde mich sehr sowohl über allgemeine, als auch spezifische Tipps freuen und kann gerne weitere Infos geben, falls benötigt.

Viele Grüße und schonmal herzlichen Dank!
 

httpdigest

Top Contributor
- Eine "Basic-Version" [...] Ich habe hier keinerlei Getter/Setter verwendet, sondern einfach alle Felder als public deklariert.
Es macht von der Performance Null/0 Unterschied, ob ein Getter/Setter verwendet wird, oder das Feld direkt angesprochen wird: Jede JVM seit ca. 1998 inlined Getter/Setter-Aufrufe agressiv.
Ist es dann beispielsweise performanter, einen Array zu erstellen, der Länge dieses Maximalwerts [...]
Ja. Eine ArrayList wird mit einer initialen Kapazität von 10 Einträgen erzeugt. Die ArrayList selbst hat also eine Kapazität (maximale Anzahl an Einträgen, bis das interne Array vergrößert werden muss) und eine Länge (die effektive Anzahl gerade hinzugefügter Elemente).
Wenn die Länge die aktuelle Kapazität übersteigt, muss ein neues Array alloziiert werden (welches aktuell 1.5x so groß ist wie das alte) und kopiert werden.
Das kann man sich sparen, wenn du den ArrayList(int) Konstruktor verwendest und eine maximale Kapazität vorinitialisierst.
Ich hoffe das alles gut verständlich ist und ich die wichtigsten Infos genannt habe.
Nein. Bei Performance in Größenordnungen von Millionen von Aufrufen geht es um ganz andere Dinge. Z.B. Speicher-/Cachelokalität. Wie genau sieht dein Speicherzugriffsmuster aus? Greifst du hier und dort wahlweise/random auf Array/List-Element zu (Cache-Thrashing)? Wie häufig alloziierst du wann welche Objekte? Wie ist überhaupt die Komplexitätsklasse des gesamten Algorithmus und kann man das eventuell verbessern?
Hier musst du einfach etwas Code zeigen. Den kann man dann Stück für Stück hinsichtlich Performance untersuchen und eventuell Verbesserungsvorschläge machen.

Was du jetzt aber schon machen kannst: Nutze einen Sampling-basierten Profiler (z.B. https://github.com/jvm-profiling-tools/async-profiler ), um erst einmal herauszufinden bzw. zu messen, welche Codestellen wie viel an Zeit kosten.
Denn Verbesserung kann man nur erreichen, wenn man weiß, wo man verbessern muss bzw. wo der Flaschenhals eigentlich ist.
 

Blut1Bart

Bekanntes Mitglied
Ohne den problematischen Code zu kennen, lässt sich nicht viel dazu sagen (ohne Glaskugel zumindest).

deshalb wollte ich nachfragen, ob ihr allgemeine Tipps habt, auf was ich bei einer solchen Art von Simulation achten sollte. Wenn ihr gute Beiträge, Webseiten, etc. dazu kennt nehme ich das alles gerne! Ich bin aber euch mehr Anfänger, deshalb fehlt mir eben auch der Blick "hinter die Kulissen".

 

Blut1Bart

Bekanntes Mitglied
Es macht von der Performance Null/0 Unterschied, ob ein Getter/Setter verwendet wird, oder das Feld direkt angesprochen wird: Jede JVM seit ca. 1998 inlined Getter/Setter-Aufrufe agressiv.
Unnötige Objekterzeugungen vermeiden ist sehr wichtig. Er hat ja auch schon angegeben, dass die zweite und dritte Variante viel langsamer ist als die erste. Die Tatsache lässt sich auch schlecht wegdiskutieren. Hast du schonmal etwas mit BigData gemacht?
 

httpdigest

Top Contributor
Unnötige Objekterzeugungen vermeiden ist sehr wichtig. Er hat ja auch schon angegeben, dass die zweite und dritte Variante viel langsamer ist als die erste. Die Tatsache lässt sich auch schlecht wegdiskutieren. Hast du schonmal etwas mit BigData gemacht?
Was hat mein Quote in deinem Post - in dem es darum ging, dass Getter/Setter inlined werden - denn damit zu tun, dass man nicht unnötig viele Objekte erzeugen soll?
Natürlich ist das Erzeugen von sehr vielen Objekten schlecht. Ich habe nirgendwo etwas anderes behauptet.
 

temi

Top Contributor
Vielleicht wäre es ein Ansatz, weniger in Objekten, als in Datensätzen zu denken und auf eine entsprechende Datenbank zu setzen.

Mir geht da gerade ein ECS (Entity Component System) durch den Kopf, wie man es in der Spieleprogrammierung verwendet.
 

Robert Zenz

Top Contributor
Ebenfalls solltest du mal einen Lauf mit VisualVM oder aehnlichem beobachten, um festzustellen ob du unnoetig Klassen erzeugst und verwirfst, und somit viel Speicherdruck hast. Also dass der Garbage Collector haeufig und lange laufen muss oder ob eben nicht. Um so oefter der Garbage Collector laufen muss, um so langsamer wird alles. Eventuell kannst du auch mit dem erhoehen der maximalen JVM Speichergroesze (zum Beispiel -Xmx 4g) dazu beitragen dass das Programm schneller laeuft. Wenn du zum Beispiel nur 2 Gigabyte zuweist, und die Simulation in etwa 1,6 Gigabyte um den Zustand zu halten, dann wird der Garbage Collector sehr of laufen, weil die JVM versucht so viel Speicher wie moeglich freizuhalten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Collections Performance einer HashMap Allgemeine Java-Themen 26
8u3631984 Frage Performance bei Linked List und Array List Allgemeine Java-Themen 5
goldmensch Datentypen Welche Methode hat die bessere Performance? Allgemeine Java-Themen 12
H Watson-Crick-Complement Performance Allgemeine Java-Themen 18
L Best Practice Auslagerung von Code = Performance Optimierung? Allgemeine Java-Themen 4
B Performance Messungen Allgemeine Java-Themen 4
J Threads verbessern die Performance NICHT ? Allgemeine Java-Themen 8
X Performance für Tomcat / Apache optimieren Allgemeine Java-Themen 2
I Performance - JDBC UPC PoolDataSoure Allgemeine Java-Themen 0
E Lambda filter performance Allgemeine Java-Themen 2
D Performance-Probleme mit Joda-Time Allgemeine Java-Themen 3
A Jasper Report Performance bei PDF erzeugen Allgemeine Java-Themen 0
A Best Practice Variablen vertauschen - Performance Allgemeine Java-Themen 1
R DBUnit Performance Probleme Allgemeine Java-Themen 0
P Performance: super explizit erwähnen oder weglassen? Allgemeine Java-Themen 5
S starke performance probleme des forums Allgemeine Java-Themen 10
C Performance Tips Allgemeine Java-Themen 13
A Performance/Speicherplatz-Nutzung bei Tests Allgemeine Java-Themen 6
R Java Performance testen Allgemeine Java-Themen 18
StrikeTom Java Performance Fragen Allgemeine Java-Themen 5
V Performance steigern Allgemeine Java-Themen 7
D Reflection-Performance Allgemeine Java-Themen 7
M Einfluss von Caching auf die Performance (große Arrays) Allgemeine Java-Themen 24
i<3java [Groovy/Grails](oder auch java) Mögliche Performance Probleme bei Mailversendung Allgemeine Java-Themen 2
D Performance Objektallokation Allgemeine Java-Themen 28
J Java Performance nicht nachvollziehbar Allgemeine Java-Themen 3
I Library für High Performance Mime Type Erkennung Allgemeine Java-Themen 8
S Performance Frage: Objekt oder static? Allgemeine Java-Themen 33
M Runtime.exec() - Performance / Frage zu Threads Allgemeine Java-Themen 5
M Performance Allgemeine Java-Themen 6
M Performance Allgemeine Java-Themen 5
E Performance website download Allgemeine Java-Themen 13
MQue Performance Methodenaufruf - if Abfrage Allgemeine Java-Themen 19
hdi Was frisst in meinem Programm den Speicher / verschlechtert die Performance Allgemeine Java-Themen 11
J Performance von Java GUI-Anwendungen Allgemeine Java-Themen 2
U Java Performance im Vergleich zu C++ in speziellem Anwendungsfall Allgemeine Java-Themen 6
S Performance und Function Call Depth Allgemeine Java-Themen 6
H Performance Vorteil durch Wechsel der JVM? Allgemeine Java-Themen 6
A Performance: byte[] in byte[][][] konvertieren Allgemeine Java-Themen 2
T Performance ArrayList#remove Allgemeine Java-Themen 8
ARadauer Performance Pptimierung -Lesen/Schreiben Allgemeine Java-Themen 10
Chris81T Performance Problem durch mehrfaches Starten eines JAVA Prog Allgemeine Java-Themen 8
G Hibernate, JTable und Performance Allgemeine Java-Themen 17
M Listener und Performance Allgemeine Java-Themen 9
P Performance: Ziehen ohne Zurücklegen (große Datenmenge) Allgemeine Java-Themen 10
D Performance: ArrayList vs. Array vs. "Eigene Liste&quot Allgemeine Java-Themen 8
M nichtreferenzierte Objekte auf NULL setzen -> Performance Allgemeine Java-Themen 4
S Ursache für schlechte Performance Allgemeine Java-Themen 2
L Java Performance Check Tool Allgemeine Java-Themen 3
S Performance von Comparator Allgemeine Java-Themen 3
egrath Performance Problem mit File-I/O Allgemeine Java-Themen 6
S Performance Problem Allgemeine Java-Themen 11
X Java Performance auf Sun Systemen bzw. generell Allgemeine Java-Themen 4
T Performance String-Operationen und StringBuffer (1.4und 1.5) Allgemeine Java-Themen 18
P miese performance bei nem BufferedImage + repaint :( Allgemeine Java-Themen 6
T Performance-Grundlagen Allgemeine Java-Themen 4
G Performance Problem bei der Übertragung Server zum Client Allgemeine Java-Themen 3
V Performance Leck finden Allgemeine Java-Themen 3
T Tile Game Performance Allgemeine Java-Themen 32
M Performance enorm langsam Allgemeine Java-Themen 26
F Performance von Reflection vs Statisches Coden Allgemeine Java-Themen 4
M Performance: Java zu C/C++ bei Datenbankanwendung Allgemeine Java-Themen 3
Y unnecessary cast & Performance Allgemeine Java-Themen 29
conan2 Performance von paint() Allgemeine Java-Themen 2
G Performance JDOM - DOM - eigene HashMap (SAX) Allgemeine Java-Themen 2
F Bilder als "Thumbnails" laden - Performance Allgemeine Java-Themen 6
S Java3D Performance optimieren Allgemeine Java-Themen 5
F Wenn ihr Performance wollt nehmt C++ Allgemeine Java-Themen 39
N Performance-Test (Geschwindigkeit von Methoden vergleichen)? Allgemeine Java-Themen 4
S Performance Test mit JMeter Allgemeine Java-Themen 2
T Performance Allgemeine Java-Themen 8
J Anfängerliste für gute Performance? Allgemeine Java-Themen 3
Luma Performance-Problem mit RandomAcces File Allgemeine Java-Themen 4
I Performance bei "String <-> Byte"-Umwandlung Allgemeine Java-Themen 4
I Performance-Probleme bei Schleife Allgemeine Java-Themen 3
C Performance von FOR Schleifen Allgemeine Java-Themen 25
C Performance Vergleich, Java vs. Tcl/Tk Allgemeine Java-Themen 3
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4
V Umgang mit fehlenden Daten in einer Java-Datenanalyseanwendung Allgemeine Java-Themen 5
M Methodenübersicht einer Klasse einsehen Allgemeine Java-Themen 14
T JNA, Aufruf der Funktionen einer dll Allgemeine Java-Themen 5
I Vom Monolith zu Services in einer Webseite Allgemeine Java-Themen 1
W Variable Initialisierung mit dem Ergebnis einer Regex Allgemeine Java-Themen 1
O Werte einer Generic LinkedList zusammenrechenen Allgemeine Java-Themen 14
C Sortieren und Selektieren einer ArrayList<Point3D> Allgemeine Java-Themen 6
A Einzelne Objekte und Unterobjekte einer ArrayList ausgeben Allgemeine Java-Themen 53
TheSepp Wie kann man Leerzeichen aus einer Array liste entfernen? Allgemeine Java-Themen 10
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
M Optimierung einer Methode (byte-Geraffel) Allgemeine Java-Themen 2
I Wie kann ich den Wert aus einer If abfrage ausgeben Allgemeine Java-Themen 23
S HTML einer Webseite 1:1 so bekommen wie es auch der Browser anzeigt? Allgemeine Java-Themen 14
melaniemueller Einzelne Zeile aus einer txt Datei in einem String speichern Allgemeine Java-Themen 12
L Java überprüfen lassen, ob sich ein gegebener Pfad / das Programm an sich auf einer CD oder Festplatte befindet Allgemeine Java-Themen 14
J (Geplante) Änderungen an einer Datei vorübergehend speichern und anwenden? Allgemeine Java-Themen 12
ME2002 Fragen aus einer Java Klausur Allgemeine Java-Themen 67
_user_q Obfuscate einer .jar-Datei mit ProGuard? Allgemeine Java-Themen 2
_user_q Verknüpfung einer .jar-Datei (liegt z. B. auf dem Desktop) im Autostart-Ordner erstellen? Allgemeine Java-Themen 20
C Parsen einer sich updatenden Html mithilfe von jsoup Allgemeine Java-Themen 4
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
LimDul Kam eine java.net.URL zu einer HashMap und ging als DNS Anfrage wieder heraus Allgemeine Java-Themen 18

Ähnliche Java Themen

Neue Themen


Oben