Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?! (https://www.delphipraxis.net/196058-geshwindigkeit-nichts-vs-round-round-gewinnt-aber-wieso.html)

KodeZwerg 19. Apr 2018 16:38

Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo, tut mir leid wegen Titel, mir fiel kein besserer ein.

Hier ein für mich noch nicht erklärbares Phänomen.
Ich lasse 500tausend mal was machen um Zeit zu messen wie lange es braucht.
Nachdem ich festgestellt habe das STR langsamer ist habe ich in der Funktion alles deaktiviert.
Programm ausführen lassen und mich wundert das Ergebniss (siehe Bild).
Wie kann etwas das nichts macht mehr Zeit kosten als etwas das was macht?


Delphi-Quellcode:
function EuroToCt (const Euro: Extended) : Int64;
var
 tmp : String;
begin
// Str(euro*100:8:0,tmp);
// Result := StrToInt(tmp);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  Ticks1, Ticks2 : UInt64;
  c: Int64;
  a: Double;
begin
 a := 1.71;
 Memo1.Clear;
 Ticks1 := GetTicks;
 for I := 0 to 500000 do c := Round(a*100);
 Ticks1 := GetTicks - Ticks1;
 Ticks2 := GetTicks;
 for I := 0 to 500000 do c := EuroToCt(a);
 Ticks2 := GetTicks - Ticks2;
 Memo1.Lines.Add(IntToStr(Ticks1)+' ROUND');
 Memo1.Lines.Add(IntToStr(Ticks2)+' STR');
end;

hoika 19. Apr 2018 16:44

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Hallo,

Delphi-Quellcode:
a := 1.71;
 for I := 0 to 500000 do c := Round(a*100);
Ich denke, das a*100 optimiert der Compiler.

Das hier vielleicht nicht.
Delphi-Quellcode:
or I := 0 to 500000 do
begin
 a := 1.71;
 c := Round(a*100);
Hast Du denn die Optimierung in der IDE eingeschaltet?

mkinzler 19. Apr 2018 16:45

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Round wird möglicherweise inline ausgeführt, es entfallen so die Funktionsaufrufe.

Zacherl 19. Apr 2018 17:00

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Zitat:

Zitat von KodeZwerg (Beitrag 1399866)
Wie kann etwas das nichts macht mehr Zeit kosten als etwas das was macht?

Weil die Funktion leider doch etwas macht :? Der String
Delphi-Quellcode:
temp
sorgt dafür, dass eine ganze Reihe an Operationen ausgeführt werden. Außerdem hast du Overhead durch das Stack-Frame, den
Delphi-Quellcode:
CALL
ansich, etc. Leider ist der Delphi Compiler sogar im Release mode so "dumm", dass er diese Anweisungen nicht raus-optimiert.

Stevie 19. Apr 2018 17:02

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Zitat:

Zitat von Zacherl (Beitrag 1399870)
Der String
Delphi-Quellcode:
temp
sorgt dafür, dass eine ganze Reihe an Operationen ausgeführt werden. Außerdem hast du Overhead durch das Stack-Frame, den
Delphi-Quellcode:
CALL
ansich, etc. Leider ist der Delphi Compiler sogar im Release mode so "dumm", dass er diese Anweisungen nicht raus-optimiert.

Selbst ohne den macht er noch stack gejuggle, was aber daran liegt dass für das Int64 Result platz auf dem Stack geschaffen wird, um am Ende in eax und edx zu packen.
Außerdem macht der Delphi Compiler keine gängigen Peephole Optimizations um unnötige vor/zurück Operationen zu eliminieren.

Kann man sehen, wenn man mal spaßeshalber auf Integer ändert (einfacheres assembly zum erklären):

Code:
Project1.dpr.15: begin
004CE91C 55               push ebp
004CE91D 8BEC            mov ebp,esp
Project1.dpr.18: end;
004CE91F 5D              pop ebp
004CE920 C20C00           ret $000c
1. ebp Register auf dem Stack sichern, weil
2. Wert aus esp in ebp gepackt wird, aber
3. Wert vom Stack wieder in ebp geholt wird
4. Funktion verlassen

Also effektiv ist nix passiert (und ja, das ist mit $O+,W- kompiliert).

himitsu 19. Apr 2018 17:08

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Zitat:

Zitat von Zacherl (Beitrag 1399870)
Weil die Funktion leider doch etwas macht :? Der String
Delphi-Quellcode:
temp
sorgt dafür, dass eine ganze Reihe an Operationen ausgeführt werden. Außerdem hast du Overhead durch das Stack-Frame, den
Delphi-Quellcode:
CALL
ansich, etc. Leider ist der Delphi Compiler sogar im Release mode so "dumm", dass er diese Anweisungen nicht raus-optimiert.

Der String sollte immer rausfliegen, egal ob Debug oder Release.

Und nein, die leere Funktion darf der Compiler eigenmächtig garnicht rauswerfen.
Woher soll er wissen, ob diese Funktion nicht eventuell gehookt wird und dann dort doch etwas gemacht wird?

Zitat:

Der String temp sorgt dafür
Temp fliet weg, da nicht verwendet, aber ob Stackframe und Co. aufgeräumt werden, weil dann doch keine Variable vor kam ... k.A.

Bei String und Dergleichen kommt vom Compiler auch noch ein Try-Finally um die ganze Funktion, damit diese Variablen immer ordnungsgemäß aufgeräumt werden.

KodeZwerg 19. Apr 2018 17:20

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Jupp, die [Var tmp:String] hat schuld, habs gerade getestet, nun beide annähernd gleich schnell.
Zur Frage wegen Compiler Optionen, die waren so wie Emba das voreingestellt hat für neue VCL Projekte, es stand auf Release.
Danke für die Aufklärung!

Zacherl 19. Apr 2018 18:11

AW: Geshwindigkeit?> Nichts Vs Round, Round gewinnt, aber wieso?!
 
Zitat:

Zitat von himitsu (Beitrag 1399874)
Zitat:

Zitat von Zacherl (Beitrag 1399870)
Weil die Funktion leider doch etwas macht :? Der String
Delphi-Quellcode:
temp
sorgt dafür, dass eine ganze Reihe an Operationen ausgeführt werden. Außerdem hast du Overhead durch das Stack-Frame, den
Delphi-Quellcode:
CALL
ansich, etc. Leider ist der Delphi Compiler sogar im Release mode so "dumm", dass er diese Anweisungen nicht raus-optimiert.

Der String sollte immer rausfliegen, egal ob Debug oder Release.

Tut er aber leider nicht. Bzw. bleibt der SEH und noch einiges an sonstigem Kram zurück, der definitiv unnötig ist an dieser Stelle.

Zitat:

Zitat von himitsu (Beitrag 1399874)
Und nein, die leere Funktion darf der Compiler eigenmächtig garnicht rauswerfen.
Woher soll er wissen, ob diese Funktion nicht eventuell gehookt wird und dann dort doch etwas gemacht wird?

Wenn die Funktion irgendwo referenziert wird, darf sie nicht wegfliegen. Externe Hooks kann der Compiler aber nicht berücksichtigen. In C/C++ wäre diese Funktion sowas von weg :-D Da kann man sagen, was man will, der Delphi Compiler optimiert einfach schlecht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:24 Uhr.

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