Möglichst gute Performance bei DataBinding?
-
Guten Tag.
Um meine Frage ein wenig zu präzisieren hier eine kurze Übersicht über mein Programm und meine Vorstellungen: Ich schriebe ein Lernprogramm für Medizinstudenten. Es ist ein WinForms-Programm mit nur einem Fenster. Dieses besitzt ein Panel in welchem zur Laufzeit verschiedene UserControls geladen werden (diese entsprechen z.B. den Tabs in einem TabPanel bzw. eigenen Fenstern, sind also meine eigentliche Arbeitsfläche!). In diesen Controls gibt es jetzt so um die 9-12 ComboBoxes, welche sehr flexibel mit Daten gefüttert werden sollen. Flexibel bedeutet hier, dass der User die Datenbindung ein-/ und ausstellen kann. Flexibel bedeutet auch, dass eine Eingabe in einer Comboxox in die DataSource übernommen werden soll und so dauerhaft gespeichert wird. Wird jetzt ein anderes Panel geladen welches eine Combobox mit der selben Datenquelle enthält, soll diese Änderung dort sofort sichtbar sein.
Ein ganz konkretes Beispiel:
Es wird das Panel zum Hinzufügen eines neuen Medikaments in die "Datenbank" geöffnet. Eine der ComboBoxes zeigt eine Liste von möglichen Nebenwirkungen an. Die gesuchte Nebenwirkungen ist noch nicht in der Liste und wird somit neu hinzugefügt. Nachdem das Hinzufügen fertig ist, wird z.B. der Lernmodus gestartet und auch hier gibt es eine ComboBox welche Nebenwirkungen anzeigt. Hier soll jetzt die soeben hinzugefügte Nebenwirkung ebenfalls in der Liste auftauchen...Als DataSource für diese ComboBoxes möchte ich lokal gespeicherte Dateien verwenden, welche ArrayLists in serialisierter Form enthalten. Eine Datenbank (SQL o.ä) möchte ich NICHT benutzen, da die Dateien einzeln unter den Studenten austauschbar sein sollen!
Meine Frage also:
Ist es sinnvoll die DataSource für jede ComboBox jeweils beim Laden des UserControls erneut zu deserialisieren und die Liste an die CBox zu binden? Es sind wie beschrieben pro UserControl 9-12 Listen mit jeweils 100 bis mehreren 100 Einträgen! Oder gibt es eine "schnellere" Methode? Ich denke da an so etwas wie: Beim Laden des Programms alle Listen deserialisieren und als 'static var' des Hauptfensters anlegen. Aber wie würde ich dann Änderungen realisieren? Nur die Liste erweitern mit .Add(..) und beim Closing-Event der Form alles neu serialisieren?
Meine momentan "beste" Idee ist die, dass ich beim Laden eines UserControls (also einer Seite) alles nötige deserialisiere, mit .Add(..) usw die statische Liste bearbeite und beim Verlassen des Contols wieder alles Serialisiere. Aber wie gesagt...macht das so sinn, oder sehe ich den Wald vor lauter Bäumen nicht?
Ich mache mir halt Sorgen, dass ständiges (De)Serialisieren der ganzen Listen auf die Performance geht, bzw. dass ein Programm den Arbeitsspeicher ohne Ende frisst, wenn man 10 Listen mit 1000 Einträgen als Variable anlegt!Habt ihr da ne gute Idee, nen Tipp, oder wenigstens ein Komment wie "Sieh dir lieber mal *** an!"?
Danke vorab,
MfG Doctore
-
Doctore schrieb:
Oder gibt es eine "schnellere" Methode? Ich denke da an so etwas wie: Beim Laden des Programms alle Listen deserialisieren und als 'static var' des Hauptfensters anlegen.
Ich hab deinen Post nur überflogen (viel zu lang), aber es deutet darauf hin, dass du noch wenig Ahnung hast. "static var" und "Hauptfenster" ist beides ganz schlecht. Aber natürlich kannst du das Laden deiner Daten optimieren. Sie sollten sowieso unbedingt in entsprechenden Klassen gekapselt werden. Wie die Klassen die Daten verwalten kann man auf zig Arten lösen, z.B. dass sie einfach im Speicher gehalten werden, oder gecached werden oder wie auch immer. Das entsprechende Fenster kommt an die Daten über eine entsprechende DAL Komponente.
-
Doctore schrieb:
bzw. dass ein Programm den Arbeitsspeicher ohne Ende frisst, wenn man 10 Listen mit 1000 Einträgen als Variable anlegt!
Rechne es halt hoch. 10 * 1000 sind 10 000. Wie viel Speicher braucht ein Eintrag bei dir? 100 Byte oder weniger? Dann hast du insgesamt 1MB Speicherverbrauch, Wahnsinn.
Und wie gesagt, du kannst ja problemlos entsprechendes Caching implementieren oder Lazy Loading. Wenn du z.B. weißt, dass die Daten einer deiner Listen eh nur selten benötigt werden, dann holst du die Daten erst, wenn sie benutzt werden.
-
Als Tipp:
Vermeide in einem ersten Durchlauf das Caching. Jegliche Art von Caching macht das Leben normalerweise unglaublich schwer. Heutige Computer sind so schnell, dass man da ruhig etwas zusätzlichen Aufwand betreiben kann. Führe erst ein Caching ein, wenn es auch wirklich nötig ist. Heisst, wenn du gemessen hast, dass es zu Performanceproblemen kommt.Das Serialisieren oder Deserialisieren von ein paar hundert Einträgen ist z.B. meistens gar nichts. Sofern ein Eintrag natürlich nicht selbst auf zig Tausend Angaben besteht
Wenn man eine vernünftige Speicherstruktur wählt (z.B. JSON) oder auch eine Datenbank (auch Embedded), dann geht sowas innerhalb von Millisekunden. Aber am besten misst du das nach.Man kann übrigens auch gewisse Datenbanken einfach untereinander austauschen. Es gibt Datenbanken, welche aus nur einem File bestehen, sieh dir dazu zum Beispiel Embedded Databases an.
Und noch als Tipp für zukünftige Beiträge:
90% deines Beitrages ist ziemlich irrelevant für die Problemstellung. Ehrlich gesagt hat mich vieles mehr verwirrt als geholfen zu verstehen, was du möchtest.Grüssli
-
Erstmal vielen Dank für die Antworten!
Dravere schrieb:
90% deines Beitrages ist ziemlich irrelevant für die Problemstellung. Ehrlich gesagt hat mich vieles mehr verwirrt als geholfen zu verstehen, was du möchtest.
Sry...wohl etwas zu gut gemeint mit "Problem genau darstellen".
Ich versuche mal zusammenzufassen: Da ich die Daten sehr oft brauchen werde, werde ich sie z.B. im Loading-Event des Programms in den Speicher schreiben. Dies realisiere ich am besten mit entsprechenden Klassen um die Listen zur Laufzeit hinreichend aktualisieren zu können.
Zu den Embedded Databases habe ich aber noch eine kleine Frage: Könnt ihr da ein gutes (freies) System empfehlen? Ich hatte mich bereits kurz in MySQL und MS SQL Server Compact eingelesen, konnte damit aber nur mäßig viel anfangen. Wenn ihr jetzt sagt, dass diese noch am einfachsten zu händeln sind, werde ich wohl in den sauren Apfel beissen und mich weiter einlesen :p
MfG Doctore
-
Im .NET Umfeld würde ich uneingeschränkt den SQL Server Compact empfehlen. Am besten versuchst du aber, unabhängig von der Datenbank zu bleiben, z.B. mit entsprechenden ORM Frameworks. Dann kannst du die Datenbank einfach austauschen, ohne den Quellcode anzupassen.
-
Mechanics schrieb:
würde ich uneingeschränkt den SQL Server Compact empfehlen
Mist
Hast du da zufällig ein gutes How-To für mich? Mein Einlesen hatte ich mal in der MSDN begonnen und dort das Bispielprogramm "nachgemacht". Aber einfach sinnfrei eine Tabelle auf ne Form ziehen bringt mich nicht besonders weit... Soll ich mich in LINQtoSQL einlesen? Mir fehlt da echt der Überblick...
Danke schonmal!
-
Ist jetzt schwer zu sagen... Inwiefern kennst du dich überhaupt mit Datenbanken aus? Die Unterschiede sind auf dem Level ja jetzt nicht so groß, du brauchst ja nichts besonderes, da fühlt sich fast jede Datenbank gleich an. Entity Framework und Linq 2 Sql kannst dir mal anschauen, wenn du willst. Ich persönlich bevorzuge als ORM Hibernate bzw. NHibernate, einfach weil ich mich da schon auskenne, das für Java und .NET verfügbar ist (wobei das unter Java immer paar Schritte voraus ist) und ich keinen Grunde sehe, mir noch was neues anzueignen, da es eigentlich alles kann.
-
hm...ok. Auf NHibernate bin ich jetzt beim ersten stöbern auch gestoßen. Werde mich da wohl mal mit auseinandersetzen. Für diese einfachen Listen ist das sicher ne gute Alternative zum (De)Serialisieren.
Mir stellt sich nur die Frage, ob ich alle Daten in Datenbanken speichern sollte? Müsste dabei letztendlich sehr viele Tabellen per Programmcode erstellen (durch den User) und die Einträge wären auch ein bisschen komplex (viele string[] z.B). Kann man das, also string[] im Speziellen, mit SQL Server Compact gut realisieren? Bin dort bisher nur auf die Formate nChar, nText usw. gestoßen. Beim Serialisieren würde ich diese halt als Object[] einer Klasse dem BinaryFormatter übergeben.
Um wie du sicher merkst: Ich kenne mich so gut wie gar nicht mit Datenbanken aus! Evtl sollte ich mich erstmal einlesen bevor ich dich weiter nerve
Aber trotzdem schonmal vielen Dank...
MfG Doctore
-
Täusch dich da mal nicht, Hibernate ist nicht so ganz trivial und für einfache Aufgaben vielleicht auch etwas überdimensioniert. Wenn du dich aber sowieso für das ganze interessierst und später noch mehr damit machen musst, ist es sicher eine gute Wahl.
String[] kann man nicht so gut in einer Datenbank speichern, würde man normalerweise über eine 1:n Beziehung realisieren. Ja, du solltest dich vielleicht etwas einlesenAber das ist jetzt auch nichts, was man in 10 Minuten lernen kann.
-
Warum nutzt du zur Serialisierung nicht JSON oder XML? Beim Programmstart deserialisierst du die Datei und hälst die Daten im Arbeitsspeicher, beim Beenden serialisierst du wieder in die XML-Datei. Auch wenn du 100000 Objekte in einer Liste im Arbeitsspeicher hälst, ist die Performance bei heutigen Rechnern kein Problem.