TListView Speicher reservieren?
-
Hi!
Ich benutze als Speicher und Anzeigemedium eines Loggers ein TListView Objekt. Nun möchte ich allerdings die Anzahl der Elemente im Vorraus schon im Speicher unterbringen, damit ich zur Laufzeit nicht das Problem einer wachsenden Anwendung habe.
Ich benutze das Ding als vsReport. Habe 5 Spalten. Und möchte nun sagen wir mal 10000 Zeilen speichern.
Genau hier liegt nun mein Problem. Ich kann zwar mit allocby dafür sorgen, daß für alle Elemente ein Speicherblock verwendet wird. Aber meine Anwendung wächst trotzdem...
Ich will das Ding nun als Ringspeicher benutzen. Schreibe 10000 Elemente. Wenn du beim 10000sten bist, lösche mir den Inhalt und lege von vorne los.
Mit der Anforderung: Die Anwendung soll nicht mit 1MB im Speicher beginnen und dann bis 10MB wachsen. Sondern gleich 10MB belegen. Fertig.
Welche Alternative habe ich nun zu folgendem Konstruktor:
Führe 10000x aus
Item->add()
Item->SubItems->Add(X)
Item->SubItems->Add(X)
Item->SubItems->Add(X)
Item->SubItems->Add(X)
-
Ich fürchte, das funktioniert so nicht. Du kannst mit AllocBy die Anzahl der Elemente festlegen, die in die ListView passen, bevor der Speicher vergrößert werden muss. Somit ist der Speicher für die Elemente fix. Es wird kein weiterer Speicher reserviert, so lange Du nicht mehr Elemente einfügst, als mittels AllocBy angegeben. ABER, da bleiben natürlich noch die AnsiStrings, die dort eingefügt werden. Diese verfügen über eine integrierte Speicherverwaltung und diese zu umgehen ist zwar möglich, allerdings würde ich 'Seiteneffekte' erwarten. Selbst wenn Du tatsächlich schon die Strings mit Leerzeichen (in der maximalen Länge der Einträge) erzeugst und in die Liste einfügst, wird spätestens beim Überschreiben der Strings ein anderer Speicherbereich verwendet. Also müsstest Du, das in dem AnsiString liegende Array selbst modifizieren. Kannst es gerne ausprobieren, aber ich würde mich damit abfinden, dass der Speicher der Anwendung wächst. Wo ist denn da das Problem? Das einzige Problem, das ich sehe, ist die pervers hohe Anzahl der Elemente im ListView. 10000 ist viel zu viel. Kein Anwender wird sich 10000 Einträge ansehen. Im ListView würde ich vielleicht die letzten 100 anzeigen, aber ich würde alle Einträge im einem LogFile protokollieren. Damit wärst Du das Problem mit dem wachsenden Speicher ebenfalls los...
-
Daß das verdammt viel ist weiss ich. Reduziert hätte ich es wohl so oder so. Alleine zum Löschen braucht der ja mehrere Sekunden.
Der Logger ist allerdings für eine Anlage gedacht, die je nach Quassel Level fröhlich vor sich hin texted, was sie gerade tut. Und was ich verhindern wollte war eben das ganze Datei Handling. Wenn der so alle 1000 Einträge rausschreibt muss ich dann auch einen Thread anwerfen, der sich darum kümmert. Dann leg ich halt alle 1000 oder 2000 Einträge ne Logfile an, in die ich die 2000 Einträge reinschreibe. Oder ich mach das Tagesabhängig und häng da an.
Ich dacht ursprünglich, daß mir TListView die Arbeit mit den Spalten erleichtert. Mittlerweile bin ich nicht mehr so ganz begeistert.
Muss ich mich auch noch um ne Log File verwaltung kümmern. ARGH...
DAs Problem ist halt, daß das ne Messsoftware ist. Und wenn die Spacken macht, wollen wir natürlich finden WO sie hakt. Da ist dann natürlich nachteilig, wenn man in Dateien rumforsten muss.
Ich baus jetzt halt so auf, daß man die letzten paar Messungen direkt mitverfolgen kann und alles was drüber ist muss man in ner Datei suchen. Basta. Da bau ich für jeden Tag ne Log Datei und die wird vollgepackt.
-
Schon mal drüber nachgedacht, für das LogFile eine Datenbank zu verwenden? Möglicherweise sparst Du Dir damit eine Menge 'Verwaltungsaufwand'. Großer Nachteil ist allerings, dass es kein direkt lesbares LogFile mehr gibt.
-
Ich hab mit Datenbanken null Erfahrung. Sprich ich bräuchte da WIEDER Zeit um mich einzuarbeiten.
Und der Logger ist in erster Linie nur als Werkzeug für mich gedacht um meiner eigentlichen Software (Die noch zu schreiben ist) diverse Kommentare zu entlocken um rausfzufinden wo ich mich "verkommuniziere". Ich hatte erst eine Übungsaufgabe programmiert um diverse WErkzeuge zu bauen, und das Ding verhaspelt sich irgendwo. Falscher Befehl zum Falschen Zeitpunkt. Das kommt davon wenn man als Threading Neuling gleichmal mit 5 oder 6 Zustandsautomaten arbeitet, von denen jeder ein eigenständiger Thread ist.
Und damit ich dann merke WO der sich vertextet baue ich gerade einen Logger. DEr bekommt dann an entsprechender Stelle im Quellcode ein fröhliches Halleluja geschickt. Brüllt mir dann A rein, wenn B reden sollte, weiss ich, daß da Bedarf zur Nachbesserung ist.Das Ding bau ich jetzt eigentlich recht simpel auf... Eigenständiges Formular. TListView. Funktion die eine Zeile hinzufügt und die von extern aufgerufen wird. Die schickt Time() mit, einen String wer geschickt hat, einen String was grade passiert DAs Formular kennen alle Threads. Die Funktion ist mit nem SynchObj. abgesichert.
Das Ding ist halt... Diplomarbeit. 31.8. Stichtag. Keine Zeit.
Wie lang brauch ich um mich in den Datenbankkram einzuklinken?
-
Na ja, das wird wohl ein paar Tage dauern... Schließlich mußt Du dich ja auch noch in SQL einarbeiten. Selbst wenn Du eine lokale Paradox-DB nimmst (das Handling dort ist sehr einfach gehalten, zB gibt es keine Transaktionen), wird das wohl immer noch den Zeitrahmen sprengen.
Wenn das LogFile nur für Dich ist, um die Fehler zu finden, würde ich mir den ganzen Aufwand sparen und eine TStringList nehmen und einfach dort alles hineinprotukollieren.
-
Hallo,
Bei einer so hohen Anzahl von Einträgen ist ein "virtueller ListView" doch besser. 10000-mal "Item->add()" dauert doch ewig... Beim virtuellen ListView geschieht das fast sofort.
Außerdem kann man dann die Daten im Hintergrund in einer TStringList halten und da kann man "Capacity" setzen :Zitat aus der BCB-Hilfe
BeschreibungMit Capacity läßt sich ermitteln, wieviel Speicherplatz für Strings reserviert ist.
Der Wert von Capacity entspricht der Anzahl von Einträgen in der String-Liste, für die Speicher reserviert wurde. Im Gegensatz dazu enthält die Eigenschaft Count die Anzahl der Strings, die sich in der Liste befinden. Aus diesem Grund ist hat Capacity immer einen Wert, der größer oder gleich dem von Count ist.
Das Hinzufügen neuer Strings bewirkt, daß der Wert von Capacity bei Bedarf erhöht wird. Eine Wertzuweisung an Capacity beeinflußt allerdings nicht den Wert der Eigenschaft Count. Capacity darf nie kleiner als Count sein, sonst wird die Liste abgeschnitten, und Count signalisiert eine größere Anzahl von Strings als tatsächlich in der Liste vorhanden. Auch der Speicher für die Strings, die aus der Liste entfernt wurden, wird in einem solchen Fall nicht freigegeben.
Nash