Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi mein record Tvektor ist ineffizient (https://www.delphipraxis.net/143192-mein-record-tvektor-ist-ineffizient.html)

vsilverlord 11. Nov 2009 18:51


mein record Tvektor ist ineffizient
 
Guten Tag,
ich hab eine einen packed record erstellt, mit dem ich mithilfe von Class operatoren Vektoren (x,y,z) berechnen kann, zb so: 8)
Delphi-Quellcode:
a,b,c:tvektor;
a := creatvektor(2,20,4);
b := -a/2;
c := a+b;
Das Problem dabei ist, dass dabei unfassbar viel unnötiger Speicher verbraucht wird, da, wenn ich mehrere Vektoren verknüpfe, diese immer ganz kopiert werden! Viel besser wäre das mit Pointer umzusetzen, :arrow:
Delphi-Quellcode:
dosomething(a,b:pointer):pointer
aber dann funktionieren die Class operatoren nicht mehr! Wie schrecklich! :evil:
Nun hab ich mir überlegt, einen neuen pointer auf tvektor zu bauen, aber da funktionieren die class operatoren erst recht nicht! :cry:
zum besseren Verständnis erst einmal den Quelltext:
Delphi-Quellcode:
unit uvektor;

interface

uses types,math,sysutils;
type
 tvektor3=packed record
 x,y,z:extended;
 //addition
 class operator add(a,b:tvektor3):tvektor3;
 class operator add(a:tvektor3;b:extended):tvektor3;
 class operator add(b:extended;a:tvektor3):tvektor3;
 //subtraktion
 class operator Subtract(a,b:tvektor3):tvektor3;
 class operator Subtract(a:tvektor3;b:extended):tvektor3;
 class operator Subtract(b:extended;a:tvektor3):tvektor3;
 //Multiplikation
 class operator Multiply(a,b:tvektor3):tvektor3;
 class operator Multiply(a:tvektor3;b:extended):tvektor3;
 class operator Multiply(b:extended;a:tvektor3):tvektor3;
 //Division
 class operator Divide(a,b:tvektor3):tvektor3;
 class operator Divide(a:tvektor3;b:extended):tvektor3;
 class operator Divide(b:extended;a:tvektor3):tvektor3;
 //negatives Vorzeichen
 class operator Negative(a:tvektor3):tvektor3;
 // größer als
 class operator GreaterThan(a,b:tvektor3):boolean;
 //kleiner als
 class operator LessThan(a,b:tvektor3):boolean;
end;
pvektor3=^tvektor3;

function createvektor(x,y,z:extended):tvektor3;
function skalarbetrag(a:tvektor3):extended;
function entfernung(a,b:tvektor3):extended;//ab
function vektortostr(a:tvektor3):string;

implementation
   //addition
   class operator tvektor3.add(a,b:tvektor3):tvektor3;
   begin
   result.x:=a.x+b.x;
   result.y:=a.y+b.y;
   result.z:=a.z+b.z;
   end;
   class operator tvektor3.add(a:tvektor3;b:extended):tvektor3;
   begin
   result.x:=a.x+b;
   result.y:=a.y+b;
   result.z:=a.z+b;
   end;
   class operator tvektor3.add(b:extended;a:tvektor3):tvektor3;
   begin
   result.x:=a.x+b;
   result.y:=a.y+b;
   result.z:=a.z+b;
   end;
   //subtraktion
   class operator tvektor3.subtract(a,b:tvektor3):tvektor3;
   begin
   result.x:= a.x-b.x;
   result.y:= a.y-b.y;
   result.z:= a.z-b.z;
   end;
   class operator tvektor3.subtract(a:tvektor3;b:extended):tvektor3;
   begin
   result.x:= a.x-b;
   result.y:= a.y-b;
   result.z:= a.z-b;
   end;
   class operator tvektor3.subtract(b:extended;a:tvektor3):tvektor3;
   begin
   result.x:= b-a.x;
   result.y:= b-a.y;
   result.z:= b-a.z;
   end;
   // multiplikation
   class operator tvektor3.Multiply(a,b:tvektor3):tvektor3;
   begin
   result.x:=a.x*b.x;
   result.y:=a.y*b.y;
   result.z:=a.z*b.z;
   end;
   class operator tvektor3.Multiply(a:tvektor3;b:extended):tvektor3;
   begin
   result.x:=a.x*b;
   result.y:=a.y*b;
   result.z:=a.z*b;
   end;
   class operator tvektor3.Multiply(b:extended;a:tvektor3):tvektor3;
   begin
   result.x:=a.x*b;
   result.y:=a.y*b;
   result.z:=a.z*b;
   end;
   //Division
   class operator tvektor3.Divide(a,b:tvektor3):tvektor3;
   begin
   result.x:=a.x/b.x;
   result.y:=a.y/b.y;
   result.z:=a.z/b.z;
   end;
   class operator tvektor3.Divide(a:tvektor3;b:extended):tvektor3;
   begin
   result.x:=a.x/b;
   result.y:=a.y/b;
   result.z:=a.z/b;
   end;
   class operator tvektor3.Divide(b:extended;a:tvektor3):tvektor3;
   begin
   result.x:=b/a.x;
   result.y:=b/a.y;
   result.z:=b/a.z;
   end;
   //Negatives Vorzeichen
   class operator tvektor3.Negative(a:tvektor3):tvektor3;
   begin
   a.x:=-a.x;
   a.y:=-a.y;
   a.z:=-a.z;
   end;
   // größer als
   class operator tvektor3.greaterthan(a,b:tvektor3):boolean;
   begin
   result:=false;
   if (a.x>b.x)or(a.y>b.y)or(a.z>b.z) then
   result:=true;
   end;
   //kleiner als
   class operator tvektor3.LessThan(a,b:tvektor3):boolean;
   begin
   result:=false;
   if (a.x<b.x)or(a.y<b.y)or(a.z<b.z) then
   result:=true;
   end;
   //standart funktionen
  function entfernung(a,b:tvektor3): extended;
  begin
    result:=skalarbetrag(a-b);
  end;

  function createvektor(x,y,z:extended):tvektor3;
  begin
    result.X:=x;
    result.Y:=y;
    result.z:=Z;
  end;
  function skalarbetrag(a:tvektor3):extended;
  begin
   result:=sqrt(power(a.x,2)+power(a.y,2)+power(a.z,2));
  end;

  function vektortostr(a:tvektor3):string;
  begin
   result:=floattostr(a.x)+'/'+floattostr(a.y)+'/'+floattostr(a.z)
  end;

end.
Meine Frage ist jetzt, wie ich diesen Quelltext optimieren kann, sodass Pointer und Class operatoren verwendet werden können!

Apollonius 11. Nov 2009 19:05

Re: mein record Tvektor ist ineffizient
 
Deklariere mal alle Parameter als const. Das sollte das Kopieren verhindern.

vsilverlord 11. Nov 2009 19:11

Re: mein record Tvektor ist ineffizient
 
ok, das hab ich gemacht. Aber gibt es keine Möglichkeit mit pointern?

Apollonius 11. Nov 2009 19:13

Re: mein record Tvektor ist ineffizient
 
Wenn du Record-Parameter als const deklarierst, werden automatisch Zeiger verwendet. In C++ entspräche das der Deklaration als const &. Eine andere Möglichkeit gibt es meines Wissens nicht.

Medium 11. Nov 2009 19:22

Re: mein record Tvektor ist ineffizient
 
Naja, man könnte halt auch einfach gleich eine Klasse statt eines Records nehmen. Ich hab in einem Projekt in C# letztens auch eine Color-Klasse die einiges mehr kann als nur RGB Werte halten gehabt, und zunächst als Struct (=Record) implementiert. Nachdem das alles irgendwie einfach lahm und stellenweise schwerfällig war (als Rückgabe eines Getters kommt dann z.B. auch eine Kopie, keine Referenz, so dass man nicht an einzelne Properties/Member zuweisen kann - z.B. in einer Liste), hab ich dann einfach mal eine Klasse draus gemacht. Fazit: Riesengewinn, auch wenn es auf den ersten Blick wie Overkill aussieht :)

Apollonius 11. Nov 2009 19:23

Re: mein record Tvektor ist ineffizient
 
Aber ohne garbage collection sind überladene Operatoren bei Referenztypen kaum zu realisieren, daher lässt Delphi für Win32 sie bei Klassen auch nicht zu.

himitsu 11. Nov 2009 19:25

Re: mein record Tvektor ist ineffizient
 
Mit Interfaces ist sowas möglich siehe http://www.delphipraxis.net/internal...t.php?t=151373

Aber wenn du die Parameter als Const definierst, dann ist das für deine Records, als wäre es mit Zeigern.

vsilverlord 11. Nov 2009 19:35

Re: mein record Tvektor ist ineffizient
 
also gut, vielen dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz