Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Prism Dynamische Arrays, Optimierung des Zugriffs!?!? (https://www.delphipraxis.net/47664-dynamische-arrays-optimierung-des-zugriffs.html)

Speedmaster 14. Jun 2005 17:02


Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Also ich habe folgende Frage zu Array Elementen, nehmen wir an ich habe eine Klasse:

Delphi-Quellcode:
TcUVarRec = record
  lConst: array of ShortString;
  // Liste der Konstanten
  lVar:  array of ShortString;
  // Liste der Variablen( Global )
end;

TcUVar = class
  private
    cVar: TcUVarRec;
  public
    procedure AddVar(vName: ShortString; vType: ShortString);
     [...]
  end;

Und die Funktion dazu:
Delphi-Quellcode:
procedure TcUVar.AddVar(vName: ShortString; vType: ShortString);
var
  i: integer;
begin
  for low(cVar.lVar) to high(cVar.lVar) do
  [...]
end;

So nun die Fragen:
- Wäre es besser das "High" in einer Variable zu Speichern und dann immer hochzuzählen??
- Ich vermute Delphi tut das High in einer Variable abspeichern während es die Schleife durchläuft??

mfg

Speedmaster

BenjaminH 14. Jun 2005 17:09

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Wenn ich jetzt nix falsch verstehe, dann ist low(cVar.lVar) immer 0.
Also wird der Compiler die Schleife vermutlich eh optimieren(klick...) und das daraus machen:
Delphi-Quellcode:
 for high(cVar.lVar) downto 0 do
  [...]
und dadurch findet der abgleich mit dem wert von High(cVar.lVar) nicht jedesmal statt und dadurch wird auch nicht die Funktion nie aufgerufen...
qed, will ich mal hoffen

Grüße Benjamin

[Edit=Uuuups]Das ist ja .NET, :oops: ich hoffe das was ich hier erzähle gilt auch dafür !

Speedmaster 14. Jun 2005 17:12

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Zitat:

Zitat von BenjaminH
Wenn ich jetzt nix falsch verstehe, dann ist low(cVar.lVar) immer 0.
Also wird der Compiler die Schleife vermutlich eh optimieren(klick...) und das daraus machen:
Delphi-Quellcode:
 for high(cVar.lVar) downto 0 do
  [...]
und dadurch findet der abgleich mit dem wert von High(cVar.lVar) nicht jedesmal statt und dadurch wird auch nicht die Funktion nie aufgerufen...
qed, will ich mal hoffen

Das hatte mich auch interresiert, aber wie gesagt die Frage war auch: Ob es besser ist eine Variable anzulegen wo immer drinsteht wie groß der Array ist, und man diese dann benutzt um das High einer Schleife rauszufinden!

brechi 14. Jun 2005 17:24

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
es wird optimiert :)

Robert_G 14. Jun 2005 18:21

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Hier sollte aber beachtet werden, dass ein .Net Compiler niemals zuviel optimieren sollte!
Das würde dem JIT die Möglichkeit rauben den Code entsprechend der bestehenden Situation und Plattform zu optimieren.
In dem Beispiel wird entgegen aller Erwartungen Test1 schneller oder mindestens genauso schnell wie Test2 sein.
Code:
public class Class1
{
    public Class1()
    {
        string[] strings = new string[] {"a", "b", "c", "d"};
   
        Test1(strings);
        Test2(strings);
    }

    void Test1(string[] stringArray)
    {
        for (int i = stringArray.GetLength(0); i >= 0; i--)
        {
            ...
        }
    }
    void Test2(string[] stringArray)
    {
        int arrayLength = stringArray.GetLength(0);

        for (int i = arrayLength; i >= 0; i--)
        {
            ...
        }
    }
}
Neben code prediction und anderen Spielereien gibt es bestimmte Typen, auf die der JIT ganz speziell reagiert.
Array gehört dazu. (Aber auch IList, IEnumerable, Attribute,...)

Speedmaster 14. Jun 2005 18:37

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Naja meine Frage war ja auch, ob es schneller ist eine VARIABLE anzulegen um dann es so zu machen:
Delphi-Quellcode:
for i:=low(MeinArray) to MaxVariable do

BenjaminH 14. Jun 2005 19:22

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Laut Brechi wird der Code optimiert, also wird diese Variable in der Schleife nie verwendet=> nein packe das nicht in eine Variable

Speedmaster 14. Jun 2005 19:54

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Zitat:

Zitat von BenjaminH
Laut Brechi wird der Code optimiert, also wird diese Variable in der Schleife nie verwendet=> nein packe das nicht in eine Variable

So meinte ich das nicht, ich habe vielleicht das falsche Beispiel gebracht:

Anstatt SethLength(Vari,high(Vari)+1) zu setzen, SethLength(Vari,MeineVar+1) und dannach inc(MeineVar)

Robert_G 14. Jun 2005 20:26

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Du machst dir Sorgen wegen ein paar kleineren Optimierungen und trotzdem verwendest du etwas in .Net, das .Net gar nicht kann? :gruebel:
Array instanzen in .Net sind IMMER fixed length. Im Gegensatz zu dyn. arrays in Delphi32 kosten Größenänderungen auch viel mehr Resourcen. Sie sind aber ganz nett als Rückgabewerte von Funktionen, die nicht mehr verändert werden müssen.
Mich würde jetzt mal interessieren, wie setLength die Werte des alten in den neuen Array kopiert.
Er kann keinen Overload für deinen value type haben, also wird er es wohl auf object boxen und danach wieder rausboxen. Was das heißt muss ich wohl nicht extra erwähnen, oder? :zwinker:

Ansonsten werfe ich das hier in den Raum: Why SetLength is evil
.Net ist einfach zu anders um dort genauso zu programmieren, wie man es vorher gewohnt war... ;)

DevilsCamp 28. Jun 2005 13:48

Re: Dynamische Arrays, Optimierung des Zugriffs!?!?
 
Zitat:

Zitat von Robert_G
Hier sollte aber beachtet werden, dass ein .Net Compiler niemals zuviel optimieren sollte!
Das würde dem JIT die Möglichkeit rauben den Code entsprechend der bestehenden Situation und Plattform zu optimieren.
In dem Beispiel wird entgegen aller Erwartungen Test1 schneller oder mindestens genauso schnell wie Test2 sein.
Code:
public class Class1
{
    public Class1()
    {
        string[] strings = new string[] {"a", "b", "c", "d"};
   
        Test1(strings);
        Test2(strings);
    }

    void Test1(string[] stringArray)
    {
        for (int i = stringArray.GetLength(0); i >= 0; i--)
        {
            ...
        }
    }
    void Test2(string[] stringArray)
    {
        int arrayLength = stringArray.GetLength(0);

        for (int i = arrayLength; i >= 0; i--)
        {
            ...
        }
    }
}

Das liegt aber wohl eher daran, dass hier intern der Startwert immer nur vor dem ersten Lauf der Schleifen gesetzt wird und danach nicht mehr von Bedeutung ist. Die Abbruchbedingung selber ist in beiden Fällen eine Konstante.

Wenn du die beiden Schleifen auf Geschwindigkeit testen willst sollte es so aussehen:
Code:
void Test1(string[] stringArray)
    {
        for (int i = 0; i <= GibMirAnzahlElementeImArray(); i++)
        {
            ...
        }
    }

    void Test2(string[] stringArray)
    {
        int arrayLength = GibMirAnzahlElementeImArray();

        for (int i = 0; i <= arrayLength; i++)
        {
            ...
        }
    }
Nur dann wird bei jedem Durchlauf die Abbruchbedingung überprüft. Und je nachdem wie komplex die Methode "GibMirAnzahlElementeImArray" ist kann dies entsprechen dauern (und wenn das Array dann noch mehrere Tausen Elemente besitzt.....)


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:13 Uhr.
Seite 1 von 2  1 2      

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