Autor Beitrag
Master_of_Magic
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56

Win 98, Win XP
D6 Pers, D2005 Arch
BeitragVerfasst: Fr 23.06.06 15:27 
Ich habe einen Record in meinem Programm:
ausblenden volle Höhe 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 //224
    Name:string[20]; //21
    X: Word; //2
    Y: Word; //2
    Z: Byte; //1
    Buildlevel: array[0..12of byte; //13
    Solarsats: Word; //2
    Temperatur: shortint; //1
    Stempelbestand: array[0..2of Cardinal; //12
    HPStempelbestand: array[0..2of Cardinal; //12
    Stempelzeitpunkt: TDateTime; //8
    Benutzerprojekte: array[0..11of Cardinal; //48
    Schiffsanzahl: array[0..17of Word; //36
    Verteidigungsanzahl: array[0..9of Word; //20
    Wirtschaftseinstellungen: array[0..5of Byte; //6
    Buildbenachrichtigungen: array[0..13of boolean; //14
    Schiffsbenachrichtigungen: array[0..18of boolean; //19
    Verteidigungsbenachrichtigungen: array[0..10of boolean; //11
  end;
  TAccount = Record
    Planet: array[0..12of TPlaneten;
    Forschungslevel: array[0..19of Byte;
    Forschungsprozente: array[0..19of Byte;
    Forschungsbenachrichtigungen: array[0..20of boolean;
    Urlaubsrechnerdaten: array[0..70of Cardinal;
    Urlaubsrechnerzeiten: array[0..9of TDateTime; //Länge 19 (Datum+Uhrzeit)
    Servershift: TDateTime;
    Umodestart: TDateTime; //8
  end;

var
  Account:Array[0..10of 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 721
Erhaltene Danke: 3



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56

Win 98, Win XP
D6 Pers, D2005 Arch
BeitragVerfasst: Do 29.06.06 19:00 
@Bernhard Geyer
zu 1. Ich hab die Daten jetzt normal ausgelesen und die nicht genutzten Bereiche mit
ausblenden 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...