Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wertezuweisung möglichst performant (https://www.delphipraxis.net/142068-wertezuweisung-moeglichst-performant.html)

MisterNiceGuy 21. Okt 2009 15:11


Wertezuweisung möglichst performant
 
Hi, ich möchte möglichst performant einem Array Werte zuweisen. Benutze ich dafür eine Schleife, also...

Delphi-Quellcode:
var i : integer;
begin
  for i := 0 to 15 do Matrix.matrix[i] := 1;
end;
ODER:

Delphi-Quellcode:
begin
  Matrix.matrix[0] := 1;
  Matrix.matrix[1] := 1;
  ...
  Matrix.matrix[15] := 1;
end;
P.S. Matrix ist ein Record.

Dax 21. Okt 2009 15:14

Re: Wertezuweisung möglichst performant
 
Probier es einfach aus ;) Die Sprungvorhersage moderner Prozessoren ist ziemlich weit entwickelt, und es gibt keinen Unterschied zwischen Feldzugriff und Arrayelementzugriff in Records - beides bedeutet eine indizierte Indirektion. Das einzige, was mir gerade einfällt, wären Pipelinefehler wegen falsch vorhergesagten Sprüngen.

Corpsman 21. Okt 2009 15:26

Re: Wertezuweisung möglichst performant
 
Heut zu Tage gibts auch die Optimierung des "Loop enroloings"

da geht der Compiler her und merkt das die Schleife "klein" ist und ersetzt diese automatisch durch die 2. Variante, so das die Schleife komplettt weg fällt.

Leider habe ich bisher noch keine Documentation zu dne Verwendeten Optimierungen von Delphi/ FPC gefunden interessant wärs bestimmt.

Apollonius 21. Okt 2009 15:27

Re: Wertezuweisung möglichst performant
 
Und für die absoluten Masochisten gibt es noch rep stosd, aber das willst du dir wahrscheinlich nicht antun.

himitsu 21. Okt 2009 15:35

Re: Wertezuweisung möglichst performant
 
es kommt auf's Array drauf an ... man könnte auch das Array als Konstante vordefinieren und dann einfach reinkopieren

shmia 21. Okt 2009 16:30

Re: Wertezuweisung möglichst performant
 
Ich würde ganz klar die Schleife (aufgehübscht mit High() und Low()) nehmen
Delphi-Quellcode:
var i : integer;
begin
  for i := Low(Matrix.matrix) to High(Matrix.matrix) do
    Matrix.matrix[i] := 1;
end;
Warum? Weil es die Absicht des Programmierers am Besten ausdrückt.

Thema Optimierung:
Optimierung ist ja im Prinzip eine schöne Sache, wenn das Programm danach schneller ist.
In diesem Falle kann man maximal einige Nanosekunden rausholen.
Wäre doch blöd, den Sourcecode nur wegen der Jagt auf einige Nanosekunden zu "versaubeuteln",
wenn man an anderer Stelle Millisekunden bis Sekunden sparen kann.

http://clean-code-developer.de/wiki/...rOptimierungen

himitsu 21. Okt 2009 17:06

Re: Wertezuweisung möglichst performant
 
Jupp, erstmal den Code schreiben, so daß er Funktioniert und später kann man an "engstellen" noch etwas optimieren.

OK, abgesehn von Optimierungen, welche von Anfang an ine wesentliche Steigerung versprechen
und wo ein späterer Umbau zuviel Arbeit macht.

Also hier kommt es dann drauf an, wie oft dieses ausgeführt wird und ob sich dann die paar Nanosekunden in der Summe überhaupt bemerkbar machen.

MisterNiceGuy 22. Okt 2009 10:11

Re: Wertezuweisung möglichst performant
 
Danke für die Antworten, falls es einen großen Performanzunterschied im fertigen Projekt gibt werd ich mal Rückmeldung geben!

QuickAndDirty 22. Okt 2009 11:44

Re: Wertezuweisung möglichst performant
 
Wenn es ein Array von Ordinaltypen ist und du nur das ganze Array mit #0 initialisieren willst
ist wohl FILLCHAR auf die Adresse des ersten Elements das beste. Das gilt auch wenn für andere Werte wenn es ein Byte oder char array ist.

Dann kannst du auch noch (also es geht immer noch nur um Initialisierung) das Array als Arraykonstante im Kode ablegen so das gar keine Zuweisung statt findet...ist wohl das schnellste.

Neutral General 22. Okt 2009 11:53

Re: Wertezuweisung möglichst performant
 
Hi,

Wollte nochmal auf Apollonius' Vorschlag zurückkommen... bzw. seinen Vorschlag unterstreichen:

"rep stosd" wird wohl das schnellstmögliche sein! :thumb:

(Und so schwer isses auch nicht. Vielleicht 3-5 Zeilen Assembler)

Edit:

Delphi-Quellcode:
// ACHTUNG: Funktioniert nur bei 4-Byte großen Datentypen!
// Für 2 Byte große Datentypen stosd durch stosw ersetzen
// Für 1 Byte große Datentypen stosd durch stosb ersetzen
procedure FillMem(Value: Integer; Dest: Pointer; Length: Integer);
asm
  mov edi, edx
  rep stosd
end;

// ...

var Test: Array[0..15] of Integer;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
  Fill(1,@Test[0],Length(Test));
  // Gucken ob alles stimmt:
  for i := 0 to 15 do
    ShowMessage(IntToStr(Test[i]));
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:28 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