Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - inc(x, (lange Formel) ) schnell ? schneller?


Delphianer23 - Fr 21.02.03 19:29
Titel: inc(x, (lange Formel) ) schnell ? schneller?
Wie sieht es mit dem Befehl inc aus?

Ist es schneller wenn man schreibt
inc(x)
statt x:=x+1; ??



wie siehts bei einer längeren Formel aus?

inc(x,sqrt(sqr(d)+d*d+d*d*d+f+s+w/2)) ??

Sollte man IMMER inc verwenden?


derDoc - Fr 21.02.03 20:05

Das kommt ganz darauf an:

Wenn du eine Konstante definierst, ist x = x +y immer schneller und entlastet dein Programm, da das somit von anderen Bereichen übernommen wird. Wenn du aber zur Laufzeit irgend etwas veränderst ist Inc(x) schneller.


Delete - Fr 21.02.03 23:50


Quelltext
1:
x := x + 1;                    

und

Quelltext
1:
Inc(x);                    

erzeugen ab D5 den gleichen Assembler-Code.


Andreas Pfau - Fr 28.02.03 20:51

Also, ich habe es nie ausprobiert, auber laut Onlinehilfe ist Inc() schneller:
Zitat:
X wird um 1 inkrementiert oder um N, wenn N angegeben ist. Das bedeutet, Inc(X) entspricht der
Anweisung X := X + 1, und Inc(X, N) ist mit der Anweisung X := X + N identisch. Inc generiert jedoch hochoptimierten Maschinencode und ist besonders für Schleifen geeignet.


Ich habe es auch ausprobiert... Inc ist im Schnitt 5% schneller... auf meinem System halt.

Ich brauche ja wohl nicht zu sagen, dass man bei Real inner "+" verwenden sollte...

Außerdem ist es egal, ob du dazu eine lange formel nimmst. Die zu berechnen braucht seine Zeit, egal ob du anschließend INC oder + machst.

Aber mal im Ernst: das spielt sich im Pikosekunden-Bereich ab. Das bringt höchstens in super-extrem-oberhammer-optimierten Schleifen was, denn ob man sich pro Durchlauf 100ps ist, das fällt kaum auf...[/quote]


Anonymous - Sa 01.03.03 10:10

Bedenkt bitte der Logik die dahintersteckt.

x := x + 1;

Bedeutet:

x := Funktion + Funktion;

Pascal wird sich nicht die Mühe machen und zuerst prüfen ob es eine Variable ist. Für Pascal werden zuerst zwei Funktionen zusammen gerechnet. Das macht eine Programmiersprache immer so. Erst bei der Auswertung der Funktion wird klar, daß die Funktion nur aus einer Variablen besteht. Das ist der Zeitverlust. Zwei mal den Anlauf nehmen um Funktionen auszuwerten, um dann festzustellen, daß es Variablen sind.

Weiter.

Inc(x);

Bedeutet

x := x + 1;

Hier ist x eine Variable. Es wird wahrscheinlich geprüft obe es ein Integer ist, aber mehr auch nicht. Es ist also klar, daß Inc schneller sein muß.

Weiter.

Inc(x, y);

Bedeutet

x := x + Funktion;

Hier ist x eine Variable und y eine Funktion. Es ist also ein Mix.


AndyB - Sa 01.03.03 10:22

Denkst du denn, dass das Programm das Überprüft? Nein, dass macht der Compiler und dessen Verarbeitungszeit hat keinen Zusammenhang mit der Runtime Geschwindigkeit.


Anonymous - Sa 01.03.03 10:46

Ich weiß jetzt nicht wie das bei einem Compiler aussieht. Ich hab mal vor vielen vielen Jahren eine eigene Programmiersprache entwickelt (nur für mich). Damals hab ich den Assemblercode einiger Programmiersprachen studiert. Deshalb weiß ich wie es bei einem Interpreter ist. Da geht die Programmiersprache nicht davon aus, daß da eine Variable ist, sondern sie geht immer von einer Funktion aus. Erst innerhalb der Funktion wird eine eventuelle Variable ausgewertet und die Funktion gibt ein Wert zurück.

Das bei einem Compiler natürlich vorher geprüft werden kann ob es sich um eine reine Variable handelt ist klar. Nachgeguckt hab ich aber nicht.


AndyB - Sa 01.03.03 10:55

Luckie hat die Begründung für den nicht vorhandenen Geschwindigkeitsunterschied bereits gepostet:

Luckie hat folgendes geschrieben:

Quelltext
1:
x := x + 1;                    

und

Quelltext
1:
Inc(x);                    

erzeugen ab D5 den gleichen Assembler-Code.


Anonymous - Sa 01.03.03 13:30

AndyB hat folgendes geschrieben:
Luckie hat die Begründung für den nicht vorhandenen Geschwindigkeitsunterschied bereits gepostet:


Na und. Es kann nicht der gleiche Code sein.

x := x + 1;

ist eine Funktion.

Inc(x);

Ist eine Prozedur.

Nur weil das Ergebnis das gleiche ist, heiß es noch lange nicht, daß es der gleiche Code ist.

x := x + 1;
x := x + 2;
x := x + 6;
x := x + 9;
x := x + 1.75;
x := x + ((1 - x) + 2);

Wenn der Compiler keine Routine hat die erkennt, daß x := x + 1 (und nur x := x + 1) auch Inc(x) sein kann, dann sind das für mich verschiedenen Arbeitsschritte.


AndyB - Sa 01.03.03 14:12

Zitat:
Na und. Es kann nicht der gleiche Code sein.

Mit Code ist der Maschinencode gemeint und der ist sehr wohl der gleiche.


Zitat:
Inc(x);
Ist eine Prozedur.

Schon mal was von inline-Prozeduren und Compiler-Magic gehört?


Hier mal ein Beispiel:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure Test(i: Integer); {register; ist sowieso Default-Aufrufkonvention}
begin
  ShowMessage(IntToStr(i));
end;

var a: Integer;
begin
  a := 10;                   mov eax, 0ah
  Inc(a, 1);                 inc eax
  Inc(a);                    inc eax
  Test(a);                   call Test
end;

var a: Integer;
begin
  a := 10;                   mov eax, 0ah
  a := a + 1;                inc eax
  a := a + 1;                inc eax
  Test(a);                   call Test
end;


Anonymous - Sa 01.03.03 14:53

Ich sehe du willst nicht verstehen was ich meine. Mir ist klar, daß

Inc(x);

und

x := x + 1;

zum Schluß das gleiche ergeben. Inc ist ein Integer um 1 erhöhen. Mehr nicht. Das ist x Wert holen, um eins erhöhen, wieder speichern. Hier braucht keiner großartig etwas zu opimieren. x := x + 1 dagegen (gehen wir mal davon aus, daß der Compiler die Vorarbeit geleistet hat) ist Wert holen, Operator bestimmen, nächste Variable holen, zusammen rechen , Wert speichern.

Mag sein, daß der Delphicompiler genial ist und intern x := x + 1 selbst zu Inc(x) optimiert. Dann ist beides das gleiche. Sonst bleibt das eine einfach Inc und das andere eine Funktion.

Ansonsten hab ich keine Lust weiter zu diskutieren.


Delete - Sa 01.03.03 17:45

Also mir wurde geasgt, das beider Code den selben Maschinencode produziren, zu bewundern im Compiler-Fenster. Ich habe es so hingenommen und nicht selber überprüft. Erstens war ich zu dem Zeitpunkt zu Faul, zweitens hatte ich besseres zu tun und drittens kann ich Assembler noch nicht mal richtig lesen.
Also überzeugt euch selber.


Andreas Pfau - Sa 01.03.03 18:23

Luckie hat Recht, ich habe nachgeschaut:

Quelltext
1:
Inc(I)                    

oder

Quelltext
1:
Inc(I, 1)                    

oder

Quelltext
1:
I := I + 1                    

wird zu

Quelltext
1:
inc eax                    


Und Andere Werte, z.B. 2:

Quelltext
1:
Inc(I, 2)                    

oder

Quelltext
1:
I := I + 2                    

werden zu

Quelltext
1:
add eax, $02                    


Ich habe es nur mit Delphi 7 Professional überprüft. I ist Integer.


Andreas Pfau - Sa 01.03.03 19:26

Und wer kann mir verraten, warum Inc() um ein paar Picosekunden schneller ist? Kann mir jemand 'nen Code posten, der das exakt misst? Da der ASM identisch ist, muss es ja ein Messfehler sein.


derDoc - Sa 01.03.03 20:32

Es kann sein, dass meine Informationen dieses Problem betreffend noch aus "alten" Zeiten stammen. Ich habe mal nachgesehen und siehe da Andreas Pfau hat Recht. Auch unter Delphi 6 ist das so. Wie das aber bei meinem alten D3 war habe ich aber noch nicht überprüft.


Delete - Sa 01.03.03 20:56

Angeblich ab D5.