Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Unpacked-Record und FileStream
Master_of_Magic - Fr 23.06.06 15:27
Titel: Unpacked-Record und FileStream
Ich habe einen Record in meinem Programm:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| type TPlaneten = Record Name:string[20]; X: Word; Y: Word; Z: Byte; Buildlevel: array[0..12] of byte; Solarsats: Word; Temperatur: shortint; Stempelbestand: array[0..2] of Cardinal; HPStempelbestand: array[0..2] of Cardinal; Stempelzeitpunkt: TDateTime; Benutzerprojekte: array[0..11] of Cardinal; Schiffsanzahl: array[0..17] of Word; Verteidigungsanzahl: array[0..9] of Word; Wirtschaftseinstellungen: array[0..5] of Byte; Buildbenachrichtigungen: array[0..13] of boolean; Schiffsbenachrichtigungen: array[0..18] of boolean; Verteidigungsbenachrichtigungen: array[0..10] of boolean; end; TAccount = Record Planet: array[0..12] of TPlaneten; Forschungslevel: array[0..19] of Byte; Forschungsprozente: array[0..19] of Byte; Forschungsbenachrichtigungen: array[0..20] of boolean; Urlaubsrechnerdaten: array[0..70] of Cardinal; Urlaubsrechnerzeiten: array[0..9] of TDateTime; Servershift: TDateTime; Umodestart: TDateTime; end;
var Account:Array[0..10] of TAccount; |
Mit dem Record arbeite ich während der Programmnutzung und beim Beenden wird er über
Streamname.WriteBuffer(Account,SizeOf(Account));
gespeichert und entsprechend geladen.
Wie das halt so ist, wenn man nicht vorrausschauend programmiert, bekommt man irgendwann ein Problem: Ich kann nun das Array of Record nicht mehr als Ganzes laden, sondern muss dir einzelnen Record-Felder per
Streamname.Read(var,SizeOf(var));
auslesen.
Dies funktioniert aber nicht so richtig, da der Record ja nicht
packed ist. Daher hab ich drei Fragen dazu:
1. Gibts 'ne elegante Möglichkeit, einen Nicht-
packed-Record mit Read auszulesen? Mein RF-Alignment ist 8.
2. Lohnt sich
packed immer, auch wenn ständig auf die Daten zugegriffen wird? Ich habe gehört, es soll langsamer sein - gibts da konkrete Messewerte?.
3. Gibt es eine Möglichkeit, den Record
packed zu speichern und damit per
Stream.Read auslesen zu können - ihn jedoch nicht
packed im Speichern zu haben?)
Und sorry für drei Fragen in einem Thread, aber es ist ja dasselbe Thema und gehört zu meinem Record. Da wollte ich nicht dreimal dasselbe posten ... ;-)
Bernhard Geyer - So 25.06.06 21:56
zu 1: Elegant weis ich nicht, aber du wirst mit TFilestream byteweise die Daten auslesen müssen
zu 2: Für Meßwerte: Selbst ist der Mann. Schleife mit 1 Mio Zugriffen auf jedes Element des Records. Einmal als Packed und einmal nicht
zu 3. Definiert dir 2 Typen. Einmal Packed und einmal nicht + Hilfsfunktionen um Record von Packed nach Unpacked zu kopieren und umgekehrt.
BenBE - So 25.06.06 22:11
Da deine Records keine Varianten Typen (Strings) enthalten, kannst Du ohne Weiteres jeden Account einfach mit FS.ReadBuffer(Account[X], SizeOf(TAccount)); auslesen ... Das hier ein ShortString enthalten ist, stört nicht, da diese anders verwaltet werden und damit kaum Compiler-Magic brauchen (und Inline gespeichert werden).
jasocul - Mo 26.06.06 08:17
Der Geschwindigkeitsunterschied ist normalerweise zu vernachlässigen.
Interessant wird es erst, wenn du viel im Hauptspeicher mit den Records hantierst. Zum Beispiel durch ständiges Umsortieren. Und auch dann merkt man das vermutlich erst, bei ein paar tausend Datensätzen.
Wenn du die Records nur zur Datenhaltung benötigst oder es sowieso nur einer ist, dann ist das zu vernachlässigen. Das Einlesen der Records von der Festplatte ist erheblich langsamer als die Verwaltung im Speicher.
Master_of_Magic - Do 29.06.06 19:00
@Bernhard Geyer
zu 1. Ich hab die Daten jetzt normal ausgelesen und die nicht genutzten Bereiche mit
Delphi-Quelltext
1:
| stream.position:=stream.position+X; |
übersprungen ... das geht auch, ist nur etwas aufwändig herauszufinden ;-)
zu 2. Ich hab das gerade mal gemacht und die Abweichung bei Lesezugriffen auf das erste Element der Arrays bzw. jedes Element des Records errechnet. Ergebnis:
Mein packed Record ist ca. 1% schneller! :roll:
zu 3. Hast du mir für die Deklaration einen Code-Schnipsel? Weil ich weiß nicht recht, wo ich das packed hinschreiben soll ... oder muss ich den kompletten Record zwei mal schreiben?
@BenBE
Das geht nicht, da in der Datei der Record ja
unpacked, im Programm jedoch jetzt
packed ist. Dein Vorschlag liefert in dem Fall ja Fehler. Aber ich hab ja jetzt 'ne Lösung gefunden (siehe zu 1.)
@jasocul
Ja, das habe ich nun auch gemerkt. Vorallem ist die Verwaltung mit Streams einfacher ...
Letztendlich macht es bei meiner Anwendung 1,8KB Platzersparnis und kaum einen Geschwindigkeitsunterschied aus. :wink:
Dann danke ich für eure Antworten, meine Frage ist damit geklärt.
Packed ist also immer sinnvoll, wenn ich den Record abspeichere und keine rechenintensiven Operationen mit ihm durchführen muss...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!