Geschwindigkeit Schleifen
-
- Beiträge: 25
- Registriert: Sa 15. Feb 2025, 13:33
Geschwindigkeit Schleifen
Anfängerfrage:
Welche Schleife wird am schnellsten abgearbeitet (FOR-,WHILE- oder Repeat-Schleife)?
Welche Schleife sollte man am besten nehmen?
Welche Schleife wird am schnellsten abgearbeitet (FOR-,WHILE- oder Repeat-Schleife)?
Welche Schleife sollte man am besten nehmen?
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2826
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Geschwindigkeit Schleifen
Du nimmst am besten die, welche zu deinem Anwendungsfall passt.
Anfängerfaustformel: Wenn du weißt wieviele Durchgänge es geben wird -> For-To-Do.
Soll etwas geschehen solange ein bestimmter Zustand vorliegt -> While-Do.
Soll etwas geschehen bis ein bestimmter Zustand vorliegt -> Repeat-Until.
Das ist jetzt natürlich etwas vereinfacht, aber auf alle Fälle kommt es auf deinen Anwendungsfall an.
Wenn du an den Punkt angekommen bist wo die Ausführungsgeschwindigkeit der Steuerung der Schleife (also nicht das was innerhalb der Schleife passiert) relevant ist, dann bist du sowieso schon bei Assembler o.Ä. angekommen.
Ignoriere also den Faktor Geschwindigkeit bitte konplett bei der Auswahl des Schleifentyps.
Gibt es ein konkretes Problem zu deiner Frage oder ist sie eher allgemein?
Anfängerfaustformel: Wenn du weißt wieviele Durchgänge es geben wird -> For-To-Do.
Soll etwas geschehen solange ein bestimmter Zustand vorliegt -> While-Do.
Soll etwas geschehen bis ein bestimmter Zustand vorliegt -> Repeat-Until.
Das ist jetzt natürlich etwas vereinfacht, aber auf alle Fälle kommt es auf deinen Anwendungsfall an.
Wenn du an den Punkt angekommen bist wo die Ausführungsgeschwindigkeit der Steuerung der Schleife (also nicht das was innerhalb der Schleife passiert) relevant ist, dann bist du sowieso schon bei Assembler o.Ä. angekommen.
Ignoriere also den Faktor Geschwindigkeit bitte konplett bei der Auswahl des Schleifentyps.
Gibt es ein konkretes Problem zu deiner Frage oder ist sie eher allgemein?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 25
- Registriert: Sa 15. Feb 2025, 13:33
Re: Geschwindigkeit Schleifen
Vielen Dank für die ausführlichen Erläuterungen und die Hinweise zum Einsatzzweck (Faustformel).
Damit kann ich was anfangen.
Die Frage ging mehr in Richtung allgemeines Verständnis. In vielen Toutorials werden die Schleifentypen erläutert, aber wann man welche Typ einsetzt bleibt dem User (=Anfänger) überlassen. Sonst würde man ja nicht ein Anfängertoutorial durcharbeiten.
Habe mal mit C, C++ und Qt angefangen. Da ist die Lernkurve extrem steil.
Zur Zeit arbeite ich einige Toutorials auf Youtube durch. Mit Lazarus konne ich im großen und ganzen relativ gut zurecht.
Damit kann ich was anfangen.
Die Frage ging mehr in Richtung allgemeines Verständnis. In vielen Toutorials werden die Schleifentypen erläutert, aber wann man welche Typ einsetzt bleibt dem User (=Anfänger) überlassen. Sonst würde man ja nicht ein Anfängertoutorial durcharbeiten.
Habe mal mit C, C++ und Qt angefangen. Da ist die Lernkurve extrem steil.
Zur Zeit arbeite ich einige Toutorials auf Youtube durch. Mit Lazarus konne ich im großen und ganzen relativ gut zurecht.
- Zvoni
- Beiträge: 414
- 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
Nachtrag zu "While" bzw. "Repeat"
"Repeat/Until" wird mindestens einmal ausgeführt, während "While" (bzw. auch For-Loop) auch keinmal ausgeführt werden kann.
Beim For-Loop werden die Grenzen EINMAL ermittelt und dann durchgezogen.
Eine Änderung der Grenze innerhalb des For-Loops hat keine Auswirkung (Was man eh nicht machen sollte).
Desweiteren sollte man bei einem For-Loop auch die Finger von der Iterator-Variablen lassen (gabs erst vor kurzem ne Diskussion im englischen Forum)
Bei Repeat bzw. While wird die Ausstiegsbedingung jedesmal neu ermittelt. Hier ist nicht mal eine Iterator-Variable notwendig
Denkt mal an Recordsets einer DB-Abfrage
Generell zu Schleifen und Speed:
Wenn du der Meinung bist, dass deine Schleife zu lang braucht, dann ist es erfahrungsgemäss in 99% der Fälle das, was innerhalb der Schleife passiert, was dich bremst, und nicht die Art, WELCHE Schleife du verwendest (Obwohl es auch da Optimierungs-Ansätze gibt)
"Repeat/Until" wird mindestens einmal ausgeführt, während "While" (bzw. auch For-Loop) auch keinmal ausgeführt werden kann.
Beim For-Loop werden die Grenzen EINMAL ermittelt und dann durchgezogen.
Eine Änderung der Grenze innerhalb des For-Loops hat keine Auswirkung (Was man eh nicht machen sollte).
Desweiteren sollte man bei einem For-Loop auch die Finger von der Iterator-Variablen lassen (gabs erst vor kurzem ne Diskussion im englischen Forum)
Bei Repeat bzw. While wird die Ausstiegsbedingung jedesmal neu ermittelt. Hier ist nicht mal eine Iterator-Variable notwendig
Denkt mal an Recordsets einer DB-Abfrage
Code: Alles auswählen
Repeat
DoSomething;
RS.Next;
Until RS.EOF;
Wenn du der Meinung bist, dass deine Schleife zu lang braucht, dann ist es erfahrungsgemäss in 99% der Fälle das, was innerhalb der Schleife passiert, was dich bremst, und nicht die Art, WELCHE Schleife du verwendest (Obwohl es auch da Optimierungs-Ansätze gibt)
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.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
Re: Geschwindigkeit Schleifen
Über die "Geschwindigkeit" habe ich mir bisher auch selten Gedanken gemacht, da hier vieles der Compiler optimieren könnte.
Eher sind schon die bereits genannten praktischen Probleme relevant:
- reicht eine feste Anzahl zum Beispiel zum Durchlaufen von Feldern
- macht es einen Unterschied bei repeat/while weil man zB manche Lauf-/Abbruchbedingen noch nicht weiß und/oder lieber positiv als negativ ausdrücken will
- und ja, ist es notwendig auf die iterierten Objekte zuzugreifen (verändern sollte man lassen wenn man kein Experte ist)
Ich kenne aus den genannten C-Sprachen und zB in Java oder Python die ziemlich elegante for-each Schleife, wo man Indexe einsparen und auch noch sicher bei den Typen sein kann. Gibt es etwas ähnliches auch in Free Pascal?
Eher sind schon die bereits genannten praktischen Probleme relevant:
- reicht eine feste Anzahl zum Beispiel zum Durchlaufen von Feldern
- macht es einen Unterschied bei repeat/while weil man zB manche Lauf-/Abbruchbedingen noch nicht weiß und/oder lieber positiv als negativ ausdrücken will
- und ja, ist es notwendig auf die iterierten Objekte zuzugreifen (verändern sollte man lassen wenn man kein Experte ist)
Ich kenne aus den genannten C-Sprachen und zB in Java oder Python die ziemlich elegante for-each Schleife, wo man Indexe einsparen und auch noch sicher bei den Typen sein kann. Gibt es etwas ähnliches auch in Free Pascal?
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2826
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Geschwindigkeit Schleifen
Aber ja:alfware17 hat geschrieben: Di 18. Feb 2025, 09:18 Ich kenne aus den genannten C-Sprachen und zB in Java oder Python die ziemlich elegante for-each Schleife, wo man Indexe einsparen und auch noch sicher bei den Typen sein kann. Gibt es etwas ähnliches auch in Free Pascal?
Code: Alles auswählen
program ForInTest;
{$MODE ObjFPC}{$H+}
uses
Classes;
var
s: String = 'Dies ist ein Test.';
c: Char;
begin
for c in s do
WriteLn(c);
end.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
- Zvoni
- Beiträge: 414
- 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
Funzt auch mit Sets/Enumsm.fuchs hat geschrieben: Di 18. Feb 2025, 09:33Aber ja:alfware17 hat geschrieben: Di 18. Feb 2025, 09:18 Ich kenne aus den genannten C-Sprachen und zB in Java oder Python die ziemlich elegante for-each Schleife, wo man Indexe einsparen und auch noch sicher bei den Typen sein kann. Gibt es etwas ähnliches auch in Free Pascal?
https://wiki.freepascal.org/for-in_loopCode: Alles auswählen
program ForInTest; {$MODE ObjFPC}{$H+} uses Classes; var s: String = 'Dies ist ein Test.'; c: Char; begin for c in s do WriteLn(c); end.
Code: Alles auswählen
program Project1;
Type
TTest = (ftEins, ftZwei, ftDrei, ftVier);
Var
T:set of TTest;
X:TTest;
begin
T:=[ftEins, ftVier];
For X In T Do Writeln(X);
end.
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.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
-
- Beiträge: 2158
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Geschwindigkeit Schleifen
For schleifen machen deutlich mehr als While oder Repeat schleifen, daher sind die natürlich offensichtlich langsamer. Aber wenn du eine While oder Repeat schleife baust die das selbe macht wie eine For schleife bist du auch nicht schneller.
Wenn du eine For schleife brauchst, brauchst du eine For schleife, simple as that.
Genauso der unterschied zwischen while und repeat, das eine macht den Vergleich oben das andere Unten, das hat natürlich auswirkungen auf die Performance, aber wenn du einen Kopfbasierten vergleich brauchst kannst du kein Repeat nehmen und wenn du einen Fußbasierten vergleich brauchst kein While.
Jedweder geschwindigkeitsunterschied ergibt sich daraus das die schleifen andere Sachen machen, du nutzt die Schleife die du brauchst, und dann musst du mit den Konsequenzen leben.
Das gesagt, es gibt eine Optimierung die oftmals gemacht wird. Wenn du eine sehr spezielle Exit condition hast die sich aus deinem Flow ergibt, dann ist das folgende:
Effizienter als die alternativen.
Wenn du eine For schleife brauchst, brauchst du eine For schleife, simple as that.
Genauso der unterschied zwischen while und repeat, das eine macht den Vergleich oben das andere Unten, das hat natürlich auswirkungen auf die Performance, aber wenn du einen Kopfbasierten vergleich brauchst kannst du kein Repeat nehmen und wenn du einen Fußbasierten vergleich brauchst kein While.
Jedweder geschwindigkeitsunterschied ergibt sich daraus das die schleifen andere Sachen machen, du nutzt die Schleife die du brauchst, und dann musst du mit den Konsequenzen leben.
Das gesagt, es gibt eine Optimierung die oftmals gemacht wird. Wenn du eine sehr spezielle Exit condition hast die sich aus deinem Flow ergibt, dann ist das folgende:
Code: Alles auswählen
repeat
// Mach was
if ExitCondition then Break;
until False;
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1663
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Geschwindigkeit Schleifen
Das hat bei mir irgendwie "Geschmäckle". Hin und wieder mache ich sowas auch. Macht den Code, gerade wenn er umfangreich ist, aber auch schwerer lesbar.Warf hat geschrieben: Di 18. Feb 2025, 11:29 [...]
Das gesagt, es gibt eine Optimierung die oftmals gemacht wird. Wenn du eine sehr spezielle Exit condition hast die sich aus deinem Flow ergibt, dann ist das folgende:Effizienter als die alternativen.Code: Alles auswählen
repeat // Mach was if ExitCondition then Break; until False;
- Zvoni
- Beiträge: 414
- 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
Ich mache sowas nur, wenn ich vor dem Ende einer Schleife rausspringen muss.Warf hat geschrieben: Di 18. Feb 2025, 11:29 Das gesagt, es gibt eine Optimierung die oftmals gemacht wird. Wenn du eine sehr spezielle Exit condition hast die sich aus deinem Flow ergibt, dann ist das folgende:Effizienter als die alternativen.Code: Alles auswählen
repeat // Mach was if ExitCondition then Break; until False;
Also eher in der Art
Code: Alles auswählen
repeat
// Mach was, dass Auswirkung auf ExitCondition hat
if ExitCondition then Break;
// Mache weiter, dass Auswirkung auf ExitCondition hat
until ExitCondition;
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.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
-
- Beiträge: 6973
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Geschwindigkeit Schleifen
Was ich in der for Schleife von Pascal vermisse, das der Step entweder +1 oder -1 sein muss. Bei C oder gar beim alten GW-BASIC sind float in der Schleife gestattet.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
- Zvoni
- Beiträge: 414
- 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
VBA/VB6Mathias hat geschrieben: Di 18. Feb 2025, 13:13 Was ich in der for Schleife von Pascal vermisse, das der Step entweder +1 oder -1 sein muss. Bei C oder gar beim alten GW-BASIC sind float in der Schleife gestattet.
Code: Alles auswählen
Dim i As Long
For i=0 To 99 Step 2
//DoSomething
Next
Und ja, vermisse ich auch.....
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.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
-
- Beiträge: 6973
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Geschwindigkeit Schleifen
Sowas habe ich auch schon vermisst, so musst man sich mit einer while-Schleife behelfen.
Code: Alles auswählen
var
i: Single
begin
for i := 0.5 to 3.5 step 0.5 do begin
foo;
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 2158
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Geschwindigkeit Schleifen
Naja in C ist der for loop nur ein glorifizierter While loop, in Pascal ist for tatsächlich semantisch deutlich stärker, so geht z.B. dasMathias hat geschrieben: Di 18. Feb 2025, 13:13 Was ich in der for Schleife von Pascal vermisse, das der Step entweder +1 oder -1 sein muss. Bei C oder gar beim alten GW-BASIC sind float in der Schleife gestattet.
Code: Alles auswählen
for i:=Integer.MaxValue-3 to Integer.MaxValue do
Bezüglich floats, hab ich mal das hier gebastelt: https://gitlab.com/freepascal.org/fpc/s ... quests/856
Erlaubt for loops über alle typen die + mit Integers überladen haben, auch selbst definierte Record typen

Re: Geschwindigkeit Schleifen
... an diesen Stellen zeigt Pascal eben seinen Ursprung als Lehr-Sprache. Das 'FOR' sollte eine vorgegebene Anzahl an Iterationen über eine Folge von Anweisungen ermöglichen. Und im Sinne dieser Definition gibt es keine Schrittweite. Hierfür sieht die Sprache das 'WHILE' vor, das keine vorab definierte Anzahl an Durchläufen erzwingt und somit auch eine freie Wahl der Schrittweite ermöglicht. Das ist einfach zu erklären und dem Einsteiger in der Lehre gut zu vermitteln.
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.
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.