Geschwindigkeit Schleifen

Für Fragen von Einsteigern und Programmieranfängern...
Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Geschwindigkeit Schleifen

Beitrag von Mathias »

Das unterscheidet Pascal aber eben von 'C', in dessen Sprachentwurf die oberste Maximen die Nützlichkeit und die Effizienz eines jeden Sprachmerkmals waren. Weil eine andere Schrittweite oder gar eine Veränderung der Schleifenlänge zur Laufzeit irgendwie hilfreich waren, hatten sie sich damit für 'C' schon ausreichend gerechtfertigt.
So wie ich mich erinner mag, ging sowas in alten Delphi und TP.

Code: Alles auswählen

var
  i: Integer;
begin
  for i:=0 to 100 do begin
    inc(i);
  end;   
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Stevie
Beiträge: 162
Registriert: Di 27. Feb 2024, 22:40

Re: Geschwindigkeit Schleifen

Beitrag von Stevie »

So wie ich mich erinner mag, ging sowas in alten Delphi und TP.
Zumindest für Turbo Pascal würde ich das bezweifeln. Schau Dir mal Seite 60 im TP3.0 Reference Manual (https://bitsavers.trailing-edge.com/pdf ... l_1986.pdf) an:
Notice that the component statement of a for statement must not contain assignments to the control variable. If the repetition is to be terminated before the final value is reached, a goto statement must be used, although such constructs are not recommended - it is better programming practice use a while or a repeat statement instead.

Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Geschwindigkeit Schleifen

Beitrag von Mathias »

Zumindest für Turbo Pascal würde ich das bezweifeln.
Also mit bp7 geht es. Habe es gerade getestet.
Dateianhänge
Bildschirmfoto vom 2025-02-18 16-47-01.png
Bildschirmfoto vom 2025-02-18 16-47-01.png (23.84 KiB) 2840 mal betrachtet
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Epcop
Beiträge: 159
Registriert: Di 29. Mai 2012, 09:36

Re: Geschwindigkeit Schleifen

Beitrag von Epcop »

Ich habe es nicht getestet, aber ich denke, egal welche Schleife, es braucht nur Bruchteile von Sekunden. Man wird den Unterschied gar nicht merken. Ich bin noch nie auf die Idee gekommen, an die Schleife selbst zu denken.

Wenn auf Geschwindigkeit optimiert werden soll, würde ich bei dem Anfangen, was in der Schleife ist. Dort ist ja meist der Zeitfresser. Vielleicht lassen sich auch noch Schleifendurchläufe verkürzen u.ä.

Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Geschwindigkeit Schleifen

Beitrag von Mathias »

Ich habe es nicht getestet, aber ich denke, egal welche Schleife, es braucht nur Bruchteile von Sekunden
Mit Assembler hatte man den Zähler an CX übergeben. Dieses Register wurde bis 0 runter gezählt und dann war die Schleife fertig.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 581
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 3.9 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
Kontaktdaten:

Re: Geschwindigkeit Schleifen

Beitrag von Niesi »

Mathias hat geschrieben: Di 18. Feb 2025, 16:48
Zumindest für Turbo Pascal würde ich das bezweifeln.
Also mit bp7 geht es. Habe es gerade getestet.
Tja, da war dann wohl an der linken Autotür auch noch eine Klingel befestigt. Damit zum Hupton auch noch Fahrradklingeln möglich ist ...

Ich kenn die Möglichkeiten auch.

Und ich überlegt damals schon: Wozu?
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Geschwindigkeit Schleifen

Beitrag von Mathias »

Und ich überlegt damals schon: Wozu?
Weil ich so eine Schleife unterbrochen habe.
Break und ähnliche kannte ich dazumal nicht.
Ohne Inet war dies recht schwierig.

Code: Alles auswählen

  for i:=0 to 100 do begin
    if erfuellt then i := 100;
  end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Geschwindigkeit Schleifen

Beitrag von Zvoni »

Anbei mal ein kleines Testprogramm.
Keine Debug-Infos, keine Rangechecks (alles abgeschaltet)

Code: Alles auswählen

program Project1;
{$mode objfpc}
Uses Sysutils;
Var
  i:Cardinal;
  t:Uint64;
begin
  t:=GetTickCount64;
  For i:=1 To 1000000000 Do Begin end;
  Writeln('For-Loop = ',GetTickCount64-t,' ms');
  i:=1;  //Reset
  t:=GetTickCount64;
  While i<=1000000000 Do Begin Inc(i); End;
  Writeln('While-Loop = ',GetTickCount64-t,' ms');
  i:=1;  //Reset
  t:=GetTickCount64;
  Repeat Inc(i); until i>1000000000;
  Writeln('Repeat-Loop = ',GetTickCount64-t,' ms');
  Readln;
end.
Meine Maschine Win10-64Bit - Laz2.2.2/FPC3.2.2 - 32 Bit

Für gar keine Optimierung (-O0)
For-Loop = 1672 ms
While-Loop = 1719 ms
Repeat-Loop = 1562 ms

Stufe 1 (-O1)
For-Loop = 1375 ms
While-Loop = 1610 ms
Repeat-Loop = 1875 ms

Stufe 2 (-O2)
For-Loop = 625 ms
While-Loop = 328 ms
Repeat-Loop = 625 ms

Stufe 3 (-O3)
For-Loop = 641 ms
While-Loop = 328 ms
Repeat-Loop = 641 ms

Interessante Ergebnisse.
Zumal der For-Loop eigentlich gar keinen Payload in der Schleife hat
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
theo
Beiträge: 10856
Registriert: Mo 11. Sep 2006, 19:01

Re: Geschwindigkeit Schleifen

Beitrag von theo »

Bei mir auf Linux (FPC 3.2.2) fällt das Ergebnis für den For-Loop besser aus.
Hier ist der grösste Unterschied beim optimierten Repeat-Loop (O2,O3).
Die restlichen Unterschiede innerhalb einer Optimierungsstufe kann man eigentlich vernachlässigen.
(Test ohne Debugger).
O0
For-Loop = 1365 ms
While-Loop = 1282 ms
Repeat-Loop = 1380 ms

O1
For-Loop = 1314 ms
While-Loop = 1290 ms
Repeat-Loop = 1273 ms

O2
For-Loop = 287 ms
While-Loop = 250 ms
Repeat-Loop = 501 ms

O3
For-Loop = 253 ms
While-Loop = 249 ms
Repeat-Loop = 502 ms

paweld
Beiträge: 85
Registriert: So 11. Jun 2023, 16:01
OS, Lazarus, FPC: Lazarus trunk, FPC fixes

Re: Geschwindigkeit Schleifen

Beitrag von paweld »

Win 10, Lazarus 4.99-trunk, FPC 3.2-fixes
x86
-O0
For-Loop = 797 ms
While-Loop = 1672 ms
Repeat-Loop = 1687 ms
-O1
For-Loop = 563 ms
While-Loop = 1672 ms
Repeat-Loop = 1609 ms
-O2
For-Loop = 219 ms
While-Loop = 203 ms
Repeat-Loop = 219 ms
-O3
For-Loop = 218 ms
While-Loop = 219 ms
Repeat-Loop = 203 ms

x86_64
-O0
For-Loop = 1625 ms
While-Loop = 1672 ms
Repeat-Loop = 1656 ms
-O1
For-Loop = 1578 ms
While-Loop = 1672 ms
Repeat-Loop = 1687 ms
-O2
For-Loop = 219 ms
While-Loop = 203 ms
Repeat-Loop = 219 ms
-O3
For-Loop = 281 ms
While-Loop = 203 ms
Repeat-Loop = 203 ms
Grüße / Pozdrawiam
paweld

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 581
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 3.9 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
Kontaktdaten:

Re: Geschwindigkeit Schleifen

Beitrag von Niesi »

-

In einer richtigen App unter Linux:

Lazarus 3.8 (rev Unknown) FPC 3.2.2 x86_64-linux-gtk2


o0
For-Loop = 1974 ms
While-Loop = 1699 ms
Repeat-Loop = 1701 ms

o1
For-Loop = 1958 ms
While-Loop = 1701 ms
Repeat-Loop = 1692 ms

o2
For-Loop = 278 ms
While-Loop = 243 ms
Repeat-Loop = 242 ms

o3
For-Loop = 276 ms
While-Loop = 240 ms
Repeat-Loop = 240 ms

o4
For-Loop = 275 ms
While-Loop = 240 ms
Repeat-Loop = 241 ms
ForDoLoopTest01.7z
(161.61 KiB) 39-mal heruntergeladen
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Mathias
Beiträge: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Geschwindigkeit Schleifen

Beitrag von Mathias »

Der Unterschied zwischen o1 und o2 ist krass, etwas das 6 fache !
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Geschwindigkeit Schleifen

Beitrag von Zvoni »

Mathias hat geschrieben: Mi 19. Feb 2025, 13:34 Der Unterschied zwischen o1 und o2 ist krass, etwas das 6 fache !
Hat mich auch erstaunt
https://wiki.freepascal.org/Optimizatio ... n_Switches

Welcher von denen ist es dann?
-O2: O1 + REMOVEEMPTYPROCS + UNUSEDPARA + REGVAR + STACKFRAME + TAILREC + CSE

Könnte man jetzt einzeln testen per
z.B. {$optimization REGVAR} als Direktive im Quellcode, um herauszufinden, welche der Optionen diesen Geschwindigkeitssprung erzeugt
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 581
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 3.9 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
Kontaktdaten:

Re: Geschwindigkeit Schleifen

Beitrag von Niesi »

Mich hat erstaunt, dass zwischen o0 und o1 praktisch kein Unterschied besteht ...
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Geschwindigkeit Schleifen

Beitrag von Zvoni »

Niesi hat geschrieben: Mi 19. Feb 2025, 13:45 Mich hat erstaunt, dass zwischen o0 und o1 praktisch kein Unterschied besteht ...
Der Unterschied der zwei Level ist PEEPHOLE (Siehe Link oben drüber), von daher vielleicht nicht wirklich überraschend.

https://en.wikipedia.org/wiki/Peephole_optimization
Ein "Klassiker" ist z.B. ersetze Multiplikation mit 2 ("x:=y*2;") mit Shift links 1 ("x:=y shl 1;"), weil der BitShift schneller ist

Wenn wir unsere Tests gemacht hätten mit einem Payload in der Schleife
z.B. "x:=y*2;" dann denke ich, würden wir schon einen Unterschied zwischen O0 und O1 sehen
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Antworten