Autor Beitrag
thebe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128

WinXP Home
D6 Enterprise
BeitragVerfasst: Fr 21.02.03 03:15 
N'Abend

Ich bin immo dabei nen Prog zu schreiben was ne 44 megs Datei in 65.000 einzelne MemoryStreams aufteilt. Eigentlich sollte das Programm ja nur diese 44 Megs plus noch nen kleines Stückchen mehr für die Stream-Klassen selbst innen Arbeitsspeicher laden, aber statt 44 megs kommen da ca. 200 megs innen Arbeitsspeicher.

Hat da irgendjemand ne genauere Ahnung von MemoryStreams wie das kommen kann ? Gibts dann noch andere Alternativen zu Streams ausser die Daten in eigenen Buffern unterzubringen ? Würde die (ohnehin viel zu hohen) Ladezeiten der Datei stark erhöhen da ich dann erst von Datei innen MemStream innen Buffer lesen müßte.

Über nen erklärendes Wort oder vllt nen kleinen Tipp wie ich das besser machen könnte, würd ich mich sehr freuen.

-Thebe
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Fr 21.02.03 08:14 
thebe hat folgendes geschrieben:
aber statt 44 megs kommen da ca. 200 megs innen Arbeitsspeicher.

Da bist du auf ein Delphi-Speichermanager Problem gestoßen, das auch bei Arrays und langen Strings auftritt.
Näheres kannst du hier bei Delphi-Praxis erfahren.


Zitat:
Würde die (ohnehin viel zu hohen) Ladezeiten der Datei stark erhöhen da ich dann erst von Datei innen MemStream innen Buffer lesen müßte.

Du musst nicht. Du kannst auch gleich aus der Datei in den Buffer lesen.

_________________
Ist Zeit wirklich Geld?
thebe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128

WinXP Home
D6 Enterprise
BeitragVerfasst: Fr 21.02.03 10:31 
Tja, schaut aus als hät ich ein Problem

ich muss nämlich leider erst innen MemStream reinschreiben, da die Datei die ich auslese nicht sortiert ist und ich teilweise mit der Leseposition des Streams teilweise hin und her fahren muss. Das kann ich mir immo noch nit so ganz mit nem Buffer vorstellen (ohne groß was neuschreiben zu müssen).

Ärgerlich, aber trotzdem danke für deine Antwort. :)

-Thebe
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Fr 21.02.03 15:53 
Die "Blöcke" die du einliest sind ja alle nur gut 700KB groß (44MB / 65000).
Es kommt zwar auf die Anwendung drauf an, aber aus deiner letzten Aussage schließe ich, daß du irgendwas sortieren willst. Warum nimmst du also nicht drekt die Datei? Ist zwar ein wenig langsamer als der speicher, dafür aber nicht so platzverschwenderisch. Du könntest ein Array[1..65000] of Integer machen und in die Werte jeweils die Byteposition schreiben (in das erste Feld 700, in das zweite 1400 usw). Dann kannst du mit
ausblenden Quelltext
1:
TFileStream.Seek(myBlocks[4], soFromBeginning);					

Bis zum 4ten Block suchen, was bei einzelnen Memory-Streams ja dem Anfang des 4ten Streams entsprechen würde. Dann die 700KB lesen und du bist beim 5ten (ja, es sind nicht genau 700KB).
Alternativ kannst du das natürlich auch beschleunigen, indem du die gesamte Datei in einen einzigen MemoryStream lädtst, was dann zwar von der Funktionsweise nicht anders wäre, dafür aber den Vorteil der kürzeren Suchzeiten und höheren Transferraten des Speichers bringen würde.

Aber wie gesagt, kommt auf die Anwendung drauf an. Was hast du denn vor, vielleicht gibt's ja eine weitere Alternative...

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
thebe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128

WinXP Home
D6 Enterprise
BeitragVerfasst: Sa 22.02.03 22:36 
Also..

Diese Datei die ich auslese, ist eine Datei in der hintereinander Grafiken abgespeichert sind. Diese Grafiken sind zeilenweise kodiert, am Anfand jeder Grafik ist eine Offset Tabelle wo ich vom Anfang der Grafik aus suchen muss, um zu Zeile XYZ zu gelangen. Zwischen den Zeilen is leider auch Schrott abgespeichert, deswegen muss ich das "sortieren".

Ich will für diese Datei einen Editor schreiben, mit dem man Grafiken einfügen/extrahieren und die Grafiken kopieren/löschen kann.

Ich hab nen Array von 65000 MemStreams, lade erst eine Index Datei ein, in der gespeichert is für welchen MemStream ich an welcher Position der Datei nachgucken muss bzw. ob der Grafik Slot überhaupt benutzt wird. Dann muss ich die Grafikdaten IM MemStream sortieren. Wenn alles durchgeladen is, kann ich sehr leicht nun neue Sachen einfügen usw.
Einziges Prob: der Speicher

Ein großer MemStream wäre unsinnig, dann könnte ich nit mehr kopieren und löschen (man stelle sich vor, der erste Slot würde gelöscht werden, und der komplette MemStream bzw. die LookUp Daten müßte neugeschrieben werden -> Chaos pur).

Den einzigen Ausweg seh ich immo darin, erst innen MemStream alles zu sortieren, dann innen Buffer alles reinzuschrieben, was aber auch wieder zu lange dauern würde. Der Sortierungsalgorithmus zieht scho anständig Zeit...

Hat jemand sowas ähnliches scho ma gemacht und das gleiche Problem gehabt ??
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 22.02.03 23:49 
aso sieht's aus.
Gibt es irgendwelche Regelmäßigkeiten? Sind die Grafiken alle gleich groß (kann man also davon ausgehen, daß alle 100KB ein neues Bild anfängt)? Ist die Lücke aus "Schrott" zwischen den Zeilen immer gleich groß (also kann man immer 10KB überspringen)?

Dann könnte man vielleicht die Grafiken so in den speicher laden, daß der dazwischenliegende Datenmüll nicht eingelesen wird, also Speicher gespart wird. Sind die Zeilen alle in der Richtigen Reihenfolge und musst du "nur" den Müll dazwischen entfernen, oder ist durch ein Interlacing-Verfahren alles so schön geschreddert worden wie auf Premiere?

Hier mein Vorschlag, wenn alle fragen mit ja beantwortet wurden:
Lies aus der Index-Datei aus, wieviele Grafiken du hast. Erzeuge für jede einen MemoryStream (sind bestimmt nicht 65000...). Dann hol dir den Offset (vom Dateianfang) der ersten Grafik, die Zeilenlänge (dürfte ja immer gleich sein, da rechteckiges Bild) und den Datenmüll (der lässt sich berechnen, indem du guckst, wieviel Platz zwischen Ende der einen Zeile und Anfang der nächsten liegt). Dann lies' die erste Zeile ein, überspring' den Müll und lies' die nächste Zeile usw. Irgendwann kommst du an's Ende der ersten Grafik und du gehst in den nächsten MemoryStream. Wieder das Offset, Zeilenlänge und Müllanteil der zweiten Grafik besorgen und Zeilenweise einlesen. Für jedes Bild in der Datei wiederholen. Jetzt hast du in den einzelnen MemoryStreams die Bilder zeilenweise ohne Müll dazwischen.

Falls die Zeilen tatsächlich alle durcheinander liegen, kannst du immer noch on the fly dekodieren:
Da du den Algorithmus zum entschlüsseln hast, kannst du die Zeilen sicherlich gleich in der richtigen Reihenfolge einlesen und ohne Müll in den Stream speichern.

Alternativ kannst du natürlich alles hintereinander machen und deine eigene Tabelle verwenden:
Für jedes Bild einen MemoryStream erzeugen. Erstes Bild einlesen, und zwar die Zeilen noch durcheinander aber den Datenmüll übersprungen. Dann hältst du in einem Array, einer Liste oder sonstwas fest, wo im MemoryStream welche Zeile liegt. Nachher die Zeilen sortieren (mit einem zweiten MemoryStream) und fertig. Du brauchst also nur einen Memorystream mehr, als du Bilder hast, oder du sortierst die Zeilen dann vom MemoryStream in den Buffer.


Wenn es absolut keine sich wiederholenden Merkmale gibt, die man regelmäßig überspringen kann, weiß ich auch nciht weiter.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert