Autor Beitrag
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Mo 11.02.13 23:20 
Hallo,

ich habe mal wieder eine Frage: Was ist Euer Meinung nach besser? Als lokale Variable den Record selber zu nehmen, oder einen POointer auf diesen? Beispiel:

ausblenden 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:
Typ
  pRec = ^Rec;
  Rec = record
   Var1 , Var2 : extended;
        end;



// entweder:
function TueWas(const Wert1, Wert2 : extended) : extended;
var
  LokalRec : Rec;
begin
  LokalRec.Var1 := Wert1;
  LokalRec.Var2 := Wert2; 
  Result := LokalRec.Var1 * LokalRec.Var2;
end;  

// oder:
function TueWasAnderes(const Wert1, Wert2 : extended) : extended;
var
  pLokalRec : pRec;
begin
  pLokalRec^.Var1 := Wert1;
  pLokalRec^.Var2 := Wert2; 
  Result := pLokalRec^.Var1 * pLokalRec^.Var2;
end;


Oder gibt es da keine Unterschiede? Bei einem habe ich schon etwas entdeckt, und das ist, wenn z.B. der Typ Rec in einer Class auftaucht, als Variable:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type
  pRec = ^Rec;
  Rec = record
          Var1 , Var2 : extended;
        end;

:
 TD = Class(TList);
       RecVar : Rec;
      end
 TForm  = Class(TForm);
             function TueWas(const Wert1, Wert2 : extended) : extended;
          end;

var
  Daten : TD;
  Form : TForm;


Dann funktioniert z.B.

ausblenden Delphi-Quelltext
1:
  Daten.RecVar.Var1 := Wert1 // in der Funktion Tuewas nicht.					


Fehler: Der linken Seite kann nichts zugewiesen werden. Erst die Überführung in eine lokale Variable des Typs Rec löst dann das Problem:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function TForm.TueWas(const Wert1, Wert2 : extended) : extended;
var
 LokalRec : Rec;
begin
 LokalRec := Daten.RecVar;
 LokalRec.Var1 := Wert1;
 LokalRec.Var2 := Wert2;
 Result := LokalRec.Var1 * LokalRec.Var2;
end;


Ich hoffe, ich habe das Ganze einleuchtend dargestellt. Ich habe in meinen Programmen oft Listen mit komplexen Strukturen (u.a. Analysenergebnisse (Konzentrationen, Elemente, Sollwerte, Vergleiche, Korrekturflags ....) und daher habe ich häufig solche Mehrfachreferenzierungen. Ich habe festgestellt, dass - die Daten stammen aus Datenbanken - das einmalige Erzeugen solch einer Liste und die nachfolgenden Operationen an dieser Liste und das abschließende Speichern der geänderten Daten in die Datenbank sehr viel schneller ablaufen als dauernd in der Datenbank "herumzuwühlen". Wie gesagt, Analysenergebnisse (z.B. Stahl mit 26 Elementen pro Analyse, 1-25 verschiedene Proben pro Auftrag und dazu noch Vergleichsproben. Da lohnt es sich schon, die Daten zu übertragen. Ich rede hier von 10 Sekunden statt 10 Minuten Abarbeitungszeit (z.B. für Korrelationsanalysen, Vergleiche mit Sollwerkstoffen, Veränderungen von Nachkommastellen und erneute Vergleiche ....). Das nur zum Hintergrund meines Anliegens.

Danke schon mal für Anmerkungen, Hinweise und Tips.

Gunther

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 11.02.13 23:43 
Deine Funktion TueWasAnderes ist so nicht korrekt, denn du benutzt einen nicht initialisierten Pointer. Wenn du einen Pointer auf einen Record verwendest, musst du den auch immer erst mit New initialisieren, damit der Speicher überhaupt reserviert und der Pointer darauf zugewiesen ist.

Die Zuweisung in einer Property funktioniert nicht als direkter Wert innerhalb des Records, da der Record beim Abrufen der Property kopiert wird. Damit arbeitest du nur auf einer temporären Kopie, würdest die Änderungen also nicht in den echten Record schreiben. Das erkennt der Compiler, da du das sicher nicht meintest.

Das ist auch der Hintergrund dessen, dass ein Pointer auf einen Record oft schneller in der Benutzung ist:
Da wird nur der Pointer kopiert, aber wenn du hingegen direkt den Record nutzt, stets der gesamte Recordinhalt.

Statt mit Pointern auf Records herumzuhantieren würde ich dir allerdings eher zu Klassen und Objekten raten. Die haben den gleichen Effekt, sind aber einfacher zu handhaben, da du nicht selbst mit Pointern arbeiten musst. Wenn du allerdings z.B. zwei solche Werte addieren möchtest, machen Records mit überladenen Operatoren natürlich am meisten Sinn.

Für diesen Beitrag haben gedankt: Tranx
Tranx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Di 12.02.13 05:57 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Deine Funktion TueWasAnderes ist so nicht korrekt, denn du benutzt einen nicht initialisierten Pointer. Wenn du einen Pointer auf einen Record verwendest, musst du den auch immer erst mit New initialisieren, damit der Speicher überhaupt reserviert und der Pointer darauf zugewiesen ist.


Danke für den Hinweis. Man, manchmal ist man aber auch verbaut. Klar muss man einen Pointer auf eine Struktur erst mit New erzeugen.

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Die Zuweisung in einer Property funktioniert nicht als direkter Wert innerhalb des Records, da der Record beim Abrufen der Property kopiert wird. Damit arbeitest du nur auf einer temporären Kopie, würdest die Änderungen also nicht in den echten Record schreiben. Das erkennt der Compiler, da du das sicher nicht meintest.

Das ist auch der Hintergrund dessen, dass ein Pointer auf einen Record oft schneller in der Benutzung ist:
Da wird nur der Pointer kopiert, aber wenn du hingegen direkt den Record nutzt, stets der gesamte Recordinhalt.

Statt mit Pointern auf Records herumzuhantieren würde ich dir allerdings eher zu Klassen und Objekten raten. Die haben den gleichen Effekt, sind aber einfacher zu handhaben, da du nicht selbst mit Pointern arbeiten musst. Wenn du allerdings z.B. zwei solche Werte addieren möchtest, machen Records mit überladenen Operatoren natürlich am meisten Sinn.


Auch danke hierfür. Habe die lokale Zuweisung zurückgenommen und arbeit nun mit dem direkten Bezug auf die Variable in der Klasse. Das macht weniger Probleme.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Di 12.02.13 09:35