Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi 'Geschwindigkeit' von lokalen/gloablen Variablen (https://www.delphipraxis.net/2987-geschwindigkeit-von-lokalen-gloablen-variablen.html)

janjan 17. Feb 2003 10:00


'Geschwindigkeit' von lokalen/gloablen Variablen
 
Ich hab bis jetzt folgenden Code für OnTimer:

Delphi-Quellcode:
procedure TForm1.UpdateTimerTimer(Sender: TObject);
var
  v1, v2, v3, v4, v5, ...: Real;
  h, m, s: String;
  temp: string;

begin
{...}
end;
Da die Routine alle 100 ms aufgerufen wird, hab ich mich gefragt, ob es nicht sinnvoller ist globale Variablen zu benutzen, da die nur einmal pro Programmaufruf initialisiert werden und Speicher zugewiesen bekommen.

So wie ich das bis jetzt verstehe wird beim Aufruf von UpdateTimerTimer jede Variable neu 'angelegt' und das kostet sicherlich Zeit.

Lieg ich mit meiner Vermutung richtig, oder ist das egal?

jbg 17. Feb 2003 10:02

Das neuanlegen geht mit einem einzigen Befehl:
Delphi-Quellcode:
asm
  sub sp, Anzahl Der Bytes die alle lokalen Variablen zusammen belegen
end;
Und ich denke das dieser eine Assemblerbefehl doch recht schnell ist und der Übersichtlichkeit hingegen globaler Variablen zu gunsten kommt.

BrainCode 17. Feb 2003 13:10

@janjan

Mach doch mal nen kleinen Benchmark (müsste mit GetTickCount gehen)!

janjan 17. Feb 2003 13:22

wenn ich dazu Zeit hätt, ich muss doch arbeiten ;)

janjan 17. Feb 2003 13:51

Komisch, komisch, scheinbar ist die lokale schneller als die globale, hier mal mein Testprogramm:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  b1,b2,b3,b4,b5,b6,b7,b8,b9,
    b10,b11,b12,b13,b14,b15,b16,b17,b18,b19: integer;
    t1, t2, t3, t4, t5, t6: string;

implementation

{$R *.dfm}

procedure lokal(i:integer);
var i1,i2,i3,i4,i5,i6,i7,i8,i9,
    i10,i11,i12,i13,i14,i15,i16,i17,i18,i19: integer;
    s1, s2, s3, s4, s5, s6: string;
begin
s1:='test';
s2:='test';
s3:='test';
s4:='test';
s5:='test';
s6:='test';
i1:=2*(i);
i2:=2*(i1);
i3:=2*(i2);
i4:=2*(i3);
i5:=2*(i4);
i6:=2*(i5);
i7:=2*(i6);
i8:=2*(i7);
i9:=2*(i8);
i10:=2*(i9);
i11:=2*(i10);
i12:=2*(i11);
i13:=2*(i12);
i14:=2*(i13);
i15:=2*(i14);
i16:=2*(i15);
i17:=2*(i16);
i18:=2*(i17);
i19:=2*(i18);
end;


procedure global(b:integer);
begin
t1:='test';
t2:='test';
t3:='test';
t4:='test';
t5:='test';
t6:='test';
b1:=2*(b);
b2:=2*(b1);
b3:=2*(b2);
b4:=2*(b3);
b5:=2*(b4);
b6:=2*(b5);
b7:=2*(b6);
b8:=2*(b7);
b9:=2*(b8);
b10:=2*(b9);
b11:=2*(b10);
b12:=2*(b11);
b13:=2*(b12);
b14:=2*(b13);
b15:=2*(b14);
b16:=2*(b15);
b17:=2*(b16);
b18:=2*(b17);
b19:=2*(b18);
end;

procedure TForm1.Button1Click(Sender: TObject);
var i,b, start, max:integer;
    stop, stop2: string;
begin
  max:=1000000;
  start:= GetTickCount;
  for i:= 1 to max do
    lokal(i);
  stop:=IntToStr(GetTickCount-Start);
  start:= GetTickCount;
  for b:= 1 to max do
    global(b);
  stop2:=IntToStr(GetTickCount-Start);

  memo1.Lines.Add('lokal '+stop+' global '+stop2);
end;

end.
Bei mir ist das Ergebnis: lokal 511 ms - global 4687 ms

Kann gut sein dass ich irgendwas übersehe...

Sharky 17. Feb 2003 14:06

Zitat:

Zitat von janjan
Komisch, komisch, scheinbar ist die lokale schneller als die globale, hier mal mein Testprogramm:


Das liegt wohl daran das lokale Variablen auf dem Stack abgelegt werden. Globale liegen (laut OH) im Datensegment der Anwendung.

Und der Zugriff auf den Stack ist dann wohl schneller!

johannes 17. Feb 2003 14:22

lokale Variablen können in die Prozessor register geladen werden, während globale variablen meist direkt aus dem Ram adrressiert werden hab ich gehört owbwohl ich mir das schlecht vorstellen kann...
(hab ich auf einer delphi optimierungs Seite gelesen weis leider nicht die adresse...)

janjan 17. Feb 2003 14:36

du meinst http://www.optimalcode.com/ ?

jbg 17. Feb 2003 14:47

Zitat:

Zitat von johannes
lokale Variablen können in die Prozessor register geladen werden, während globale variablen meist direkt aus dem Ram adrressiert werden

In diesem Fall ist es nicht so. Wenn man die Compiler-Hinweise beachtet, kann man feststellen, dass der Optimierer im Compiler bei der lokal Prozedur alle Berechnungen entfernt hat, da diese nicht benötigt werden.
Zudem ist es beim Zuweisen an globalen Strings ein nicht zu vernachläsigender Mehr-Overhead zu bewerkstelligen. So muss aus bestimmten Gründen der gesamte String erst einmal Kopiert werden bevor er zugewiesen wird. Bei lokelen Variablen bestehen diese Gründe nicht, und es muss nicht kopiert werden.


Zitat:

Und der Zugriff auf den Stack ist dann wohl schneller!
Speicher ist Speicher. Und der ist immer gleich schnell.


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