während (1) Vs. für (;;) Gibt es einen Geschwindigkeitsunterschied?

154

Lange Version...

Ein Mitarbeiter behauptete heute, nachdem er meine Verwendung while (1)in einem Perl-Skript gesehen hatte, for (;;)das schneller ist. Ich argumentierte, dass sie gleich sein sollten, in der Hoffnung, dass der Dolmetscher alle Unterschiede optimieren würde. Ich habe ein Skript eingerichtet, das 1.000.000.000 für Schleifeniterationen und die gleiche Anzahl von while-Schleifen ausführt und die Zeit dazwischen aufzeichnet. Ich konnte keinen nennenswerten Unterschied feststellen. Mein Kollege sagte, ein Professor habe ihm gesagt, dass der while (1)einen Vergleich mache 1 == 1und der for (;;)nicht. Wir haben den gleichen Test mit dem 100-fachen der Anzahl der Iterationen mit C ++ wiederholt und der Unterschied war vernachlässigbar. Es war jedoch ein anschauliches Beispiel dafür, wie viel schneller kompilierter Code im Vergleich zu einer Skriptsprache sein kann.

Kurzfassung ...

Gibt es einen Grund, eine while (1)gegenüber einer zu bevorzugen, for (;;)wenn Sie eine Endlosschleife benötigen, aus der Sie ausbrechen können?

Hinweis: Wenn es aus der Frage nicht klar ist. Dies war eine rein lustige akademische Diskussion zwischen ein paar Freunden. Mir ist bewusst, dass dies kein überaus wichtiges Konzept ist, über das sich alle Programmierer quälen sollten. Vielen Dank für all die tollen Antworten, die ich (und ich bin sicher andere) aus dieser Diskussion gelernt habe.

Update: Der oben genannte Mitarbeiter hat mit einer Antwort unten gewogen.

Zitiert hier für den Fall, dass es begraben wird.

Es kam von einem AMD-Montageprogrammierer. Er erklärte, dass C-Programmierer (die Leute) nicht erkennen, dass ihr Code Ineffizienzen aufweist. Er sagte heute jedoch, dass gcc-Compiler sehr gut sind und Leute wie ihn aus dem Geschäft bringen. Er sagte zum Beispiel, und erzählte mir von dem while 1vs for(;;). Ich benutze es jetzt aus Gewohnheit, aber gcc und insbesondere Dolmetscher werden heutzutage für beide die gleiche Operation (einen Prozessorsprung) ausführen, da sie optimiert sind.

Copas
quelle
4
Ich bin neugierig. Warum brauchen Sie eine Endlosschleife in einem Perl-Skript? Sie programmieren offensichtlich keinen Treiber oder eine Systemsache ... Unendlich ist ziemlich lang :-)
Luc M
125
Welche Endlosschleife ist am schnellsten? LOL ... "Mein neuer Computer ist so schnell, dass er in knapp einer Stunde eine Endlosschleife durchläuft ..." ;-)
Arjan Einbu
8
War das ein Professor für Soziologie, der ihm das sagte? In der Neuzeit ist der Code, den Sie eingeben, nicht das, was der Computer am Ende sieht.
Brian D Foy
5
Ich gehe davon aus, dass die Zeit, die Sie zum Testen benötigt haben, viel länger war als die Zeit, die möglicherweise eingespart wurde, wenn Sie wissen, welche schneller ist, wenn auch nicht. selbst wenn Sie es über beide Programmierzeiten amortisieren.
Peter Recore
4
Warum sollte der Compiler jemals Code generieren, um einen Test durchzuführen, von dem er weiß, dass er keine Nebenwirkungen hat und dessen Ergebnis der Compiler bereits kennt? Das macht keinen Sinn.
David Schwartz

Antworten:

218

In Perl führen sie zu denselben Opcodes:

$ perl -MO=Concise -e 'for(;;) { print "foo\n" }'
a  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 2 -e:1) v ->3
9     <2> leaveloop vK/2 ->a
3        <{> enterloop(next->8 last->9 redo->4) v ->4
-        <@> lineseq vK ->9
4           <;> nextstate(main 1 -e:1) v ->5
7           <@> print vK ->8
5              <0> pushmark s ->6
6              <$> const[PV "foo\n"] s ->7
8           <0> unstack v ->4
-e syntax OK

$ perl -MO=Concise -e 'while(1) { print "foo\n" }'
a  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 2 -e:1) v ->3
9     <2> leaveloop vK/2 ->a
3        <{> enterloop(next->8 last->9 redo->4) v ->4
-        <@> lineseq vK ->9
4           <;> nextstate(main 1 -e:1) v ->5
7           <@> print vK ->8
5              <0> pushmark s ->6
6              <$> const[PV "foo\n"] s ->7
8           <0> unstack v ->4
-e syntax OK

Ebenso in GCC:

#include <stdio.h>

void t_while() {
    while(1)
        printf("foo\n");
}

void t_for() {
    for(;;)
        printf("foo\n");
}

    .file   "test.c"
    .section    .rodata
.LC0:
    .string "foo"
    .text
.globl t_while
    .type   t_while, @function
t_while:
.LFB2:
    pushq   %rbp
.LCFI0:
    movq    %rsp, %rbp
.LCFI1:
.L2:
    movl    $.LC0, %edi
    call    puts
    jmp .L2
.LFE2:
    .size   t_while, .-t_while
.globl t_for
    .type   t_for, @function
t_for:
.LFB3:
    pushq   %rbp
.LCFI2:
    movq    %rsp, %rbp
.LCFI3:
.L5:
    movl    $.LC0, %edi
    call    puts
    jmp .L5
.LFE3:
    .size   t_for, .-t_for
    .section    .eh_frame,"a",@progbits
.Lframe1:
    .long   .LECIE1-.LSCIE1
.LSCIE1:
    .long   0x0
    .byte   0x1
    .string "zR"
    .uleb128 0x1
    .sleb128 -8
    .byte   0x10
    .uleb128 0x1
    .byte   0x3
    .byte   0xc
    .uleb128 0x7
    .uleb128 0x8
    .byte   0x90
    .uleb128 0x1
    .align 8
.LECIE1:
.LSFDE1:
    .long   .LEFDE1-.LASFDE1
.LASFDE1:
    .long   .LASFDE1-.Lframe1
    .long   .LFB2
    .long   .LFE2-.LFB2
    .uleb128 0x0
    .byte   0x4
    .long   .LCFI0-.LFB2
    .byte   0xe
    .uleb128 0x10
    .byte   0x86
    .uleb128 0x2
    .byte   0x4
    .long   .LCFI1-.LCFI0
    .byte   0xd
    .uleb128 0x6
    .align 8
.LEFDE1:
.LSFDE3:
    .long   .LEFDE3-.LASFDE3
.LASFDE3:
    .long   .LASFDE3-.Lframe1
    .long   .LFB3
    .long   .LFE3-.LFB3
    .uleb128 0x0
    .byte   0x4
    .long   .LCFI2-.LFB3
    .byte   0xe
    .uleb128 0x10
    .byte   0x86
    .uleb128 0x2
    .byte   0x4
    .long   .LCFI3-.LCFI2
    .byte   0xd
    .uleb128 0x6
    .align 8
.LEFDE3:
    .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
    .section    .note.GNU-stack,"",@progbits

Ich denke, die Antwort ist, dass sie in vielen Compilern gleich sind. Natürlich muss dies für einige andere Compiler nicht unbedingt der Fall sein, aber es besteht die Möglichkeit, dass der Code innerhalb der Schleife ein paar tausend Mal teurer ist als die Schleife selbst. Wen interessiert das?

bdonlan
quelle
15
Versuchen Sie es mit B :: Deparse. Wenn Sie eine unendliche for-Schleife deparieren, wird eine while-Schleife zurückgegeben: P
Kent Fredric
27
"In Perl ergeben sie die gleichen Opcodes" ... ja, aber welche ist schneller? :-)
der Blechmann
6
Ich finde es toll, dass gcc printf () durch put () ersetzt, da es nur ein Argument gibt und daher nichts zu formatieren ist - schneller und sicherer! (gcc prüft auch Formatierungs-Tags anhand der Liste der variablen Argumente.)
Lee D
@ the Tin Man: Sie sind gleichwertig, weil der Computer genau die gleichen Operationen
ausführt
1
@snap, es ist nicht "völlig" falsch, es konzentriert sich nur auf die Laufzeitkosten. Ich kann mir nicht vorstellen, welche Situation dazu führen würde, dass die Analysezeit von Endlosschleifen der entscheidende Faktor dafür ist, wie schnell Ihr Programm läuft
bdonlan
55

Mit GCC scheinen beide in derselben Assemblersprache zu kompilieren:

L2:
        jmp     L2
Martin Cote
quelle
20
Verwenden von GCC mit der Option -S (zusammenbauen, nicht verknüpfen)
Martin Cote
54

Es gibt nicht viel Grund, einen dem anderen vorzuziehen. Ich denke das while(1)und ist vor allem while(true)besser lesbar als for(;;), aber das ist nur meine Präferenz.

Bill die Eidechse
quelle
94
#define EVER ;; für (EVER) finde ich das immer amüsant.
Tom
19
Wie wäre es mit #define ever (;;) für immer;
Martin Cote
16
Beide scheinen auf den ersten Blick besser lesbar zu sein, aber ich versuche, keine neuen Schlüsselwörter für meinen Wartungsprogrammierer (normalerweise mich) zu definieren, um sich den Kopf zu kratzen.
Bill the Lizard
13
@Martin, das nicht funktioniert, weil # define's nicht innerhalb eines Tokens ersetzt werden und foreveres sich um ein eigenes Token handelt.
Lily Chung
2
"Ich versuche, keine neuen Schlüsselwörter für meine Wartung zu definieren" - wenn nur mehr Leute diese Haltung einnehmen würden, würde ich mich nicht jedes Mal, wenn ich mich umdrehte, an all diese verrückten und magischen Spielereien klammern!
Tchrist
31

Es gibt keinen Unterschied nach dem Standard. 6.5.3 / 1 hat:

Die for-Anweisung

for ( for-init-statement ; conditionopt ; expressionopt ) statement

ist äquivalent zu

{
  for-init-statement
  while ( condition ) {
    statement
    expression ;
  }
}

Und 6.5.3 / 2 hat:

Eine oder beide Bedingungen und der Ausdruck können weggelassen werden. Eine fehlende Bedingung macht die implizite while-Klausel gleichbedeutend mit while (true).

Also nach dem C ++ Standard der Code:

for (;;);

ist genau das gleiche wie:

{
  while (true) {
    ;
    ;
  }
}
Richard Corden
quelle
4
Das bezieht sich überhaupt nicht auf den generierten Code oder die Leistung. Der Standard definiert nur die Funktionalität. Die Leistung wird natürlich gleich sein.
Potatoswatter
1
Ich glaube nicht, dass ein Leistungsunterschied gegen die Als-ob-Regel verstößt. Wenn dies der Fall wäre, könnten Compiler Ihren Code nach der Als-ob-Regel nicht beschleunigen, indem sie beispielsweise unabhängige Anweisungen neu anordnen. Compiler machen genau das. Aber meine Kopie des Standards ist weit oben.
Steve Jessop
28

Der Visual C ++ - Compiler, mit dem eine Warnung für ausgegeben wird

while (1) 

(konstanter Ausdruck) aber nicht für

for (;;)

Ich habe for (;;)aus diesem Grund die Praxis des Bevorzugens fortgesetzt , aber ich weiß nicht, ob der Compiler dies heutzutage noch tut.

Sean e
quelle
Die Warnung ist wahrscheinlich, weil Sie while (1) anstelle von while (true) verwendet haben
jrharshath
16
wahr ist eine Konstante. während (wahr) ein konstanter Ausdruck ist. Für alle Interessierten ist die Warnung C4127 hier dokumentiert: msdn.microsoft.com/en-us/library/6t66728h(VS.80).aspx
e
Ja, die Warnung ist sowohl für 1 als auch für true weiterhin vorhanden. Das ist der Grund, warum ich immer für (;;)
Elviss Strazdins
26

for(;;) ist ein Zeichen weniger, das Sie eingeben müssen, wenn Sie in diese Richtung gehen möchten, um die Dinge zu optimieren.

Chris Bartow
quelle
21
Gut zu wissen zum Golfen. Ansonsten ein schlechter Grund, eine Syntax zu wählen.
Adam Bellaire
@AdamBellaire Knappheit erhöht häufig die Lesbarkeit ab einer bestimmten Fähigkeitsschwelle.
Vektor Gorgoth
20

Turbo C mit diesen alten Compilern for(;;)führt dann zu schnellerem Code while(1).

Heutzutage optimieren gcc, Visual C (ich denke fast alle) Compiler gut, und CPUs mit 4,7 MHz werden selten verwendet.

In jenen Tagen for( i=10; i; i-- )war a schneller als for( i=1; i <=10; i++ ), da der Vergleich i0 ist, was zu einem bedingten CPU-Zero-Flag-Sprung führt. Und das Zero-Flag wurde mit der letzten Dekrementierungsoperation geändert ( i-- ), es ist keine zusätzliche cmp-Operation erforderlich.

    call    __printf_chk
    decl    %ebx          %ebx=iterator i 
    jnz     .L2
    movl    -4(%ebp), %ebx
    leave

und hier mit for(i=1; i<=10; i++)mit extra cmpl:

    call    __printf_chk
    incl    %ebx
    cmpl    $11, %ebx
    jne     .L2
    movl    -4(%ebp), %ebx
    leave
Lutz L.
quelle
13

Für alle Leute, die argumentieren, Sie sollten keine unbestimmten while-Schleifen verwenden und dumme Sachen vorschlagen, wie die Verwendung von offenen Goto (ernsthaft, autsch)

while (1) {
     last if( condition1 );
     code();
     more_code(); 
     last if( condition2 ); 
     even_more_code(); 
}

Kann auf andere Weise nicht wirklich effektiv dargestellt werden. Nicht ohne eine Exit-Variable zu erstellen und schwarze Magie zu betreiben, um sie synchron zu halten.

Wenn Sie eine Vorliebe für die goto-artigere Syntax haben, verwenden Sie etwas Vernünftiges, das den Umfang einschränkt.

flow: { 

   if ( condition ){ 
      redo flow;
   }
   if ( othercondition ){ 
       redo flow;
   }
   if ( earlyexit ){ 
       last flow;
   }
   something(); # doesn't execute when earlyexit is true 
}

Letztendlich ist Geschwindigkeit nicht so wichtig

Es ist eine enorme Zeitverschwendung, sich Gedanken darüber zu machen, wie effektiv die Geschwindigkeit verschiedener Schleifenkonstrukte ist. Vorzeitige Optimierung durch und durch. Ich kann mir keine Situation vorstellen, in der Profiling-Code Engpässe bei der Auswahl des Schleifenkonstrukts festgestellt hat.

Im Allgemeinen ist es das Wie der Schleife und das Was der Schleife.

Sie sollten die Lesbarkeit und Prägnanz "optimieren" und alles schreiben, was am besten geeignet ist, um das Problem dem nächsten armen Trottel zu erklären, der Ihren Code findet.

Wenn Sie den Trick "goto LABEL" verwenden, den jemand erwähnt hat, und ich Ihren Code verwenden muss, sollten Sie darauf vorbereitet sein, mit einem offenen Auge zu schlafen, insbesondere wenn Sie dies mehr als einmal tun, da solche Dinge schrecklich Spaghetti-Code erzeugen.

Nur weil Sie Spaghetti-Code erstellen können , heißt das nicht, dass Sie es sollten

Kent Fredric
quelle
9

Aus Stroustrup, TC ++ PL (3. Auflage), §6.1.1:

Die merkwürdige Notation for (;;)ist die Standardmethode, um eine Endlosschleife anzugeben. man könnte es "für immer" aussprechen. [...] while (true)ist eine Alternative.

Ich bevorzuge for (;;).

Hans W.
quelle
9

Wenn der Compiler keine Optimierung durchführt, for(;;)wäre er immer schneller alswhile(true) . Dies liegt daran, dass while-Anweisung die Bedingung jedes Mal auswertet, for-Anweisung jedoch ein bedingungsloser Sprung ist. Wenn der Compiler den Kontrollfluss optimiert, werden möglicherweise einige Opcodes generiert. Sie können den Demontagecode sehr einfach lesen.

PS Sie könnten eine Endlosschleife wie folgt schreiben:

#define EVER ;;
  //...
  for (EVER) {
    //...
  }
silverbullettt
quelle
In der heutigen Zeit sollte NIEMALS durch EFD (Teenager sprechen) ersetzt werden! Im Ernst, ich benutze es einfach für (;;) {}. Ich habe vor langer Zeit online über die Unterschiede zwischen den beiden gelesen (als ich jünger war und nicht wusste, dass sie gleich sind) und bin einfach bei dem geblieben, was ich gelesen habe.
Bja
8

Ich habe einmal davon gehört.

Es kam von einem AMD-Montageprogrammierer. Er erklärte, dass C-Programmierer (die Leute) nicht erkennen, dass ihr Code Ineffizienzen aufweist. Er sagte heute jedoch, dass gcc-Compiler sehr gut sind und Leute wie ihn aus dem Geschäft bringen. Er sagte zum Beispiel, und erzählte mir von dem while 1vs for(;;). Ich benutze es jetzt aus Gewohnheit, aber gcc und insbesondere Dolmetscher werden heutzutage für beide die gleiche Operation (einen Prozessorsprung) ausführen, da sie optimiert sind.

Jimmie Clark
quelle
5

In einem optimierten Build einer kompilierten Sprache sollte es keinen nennenswerten Unterschied zwischen den beiden geben. Keiner sollte zur Laufzeit Vergleiche durchführen, er führt nur den Schleifencode aus, bis Sie die Schleife manuell verlassen (z break. B. mit a ).

Charlie
quelle
3

Ich bin überrascht, dass niemand richtig for (;;)gegen while (1)Perl getestet hat !

Da Perl eine interpretierte Sprache ist, besteht die Zeit zum Ausführen eines Perl-Skripts nicht nur aus der Ausführungsphase (die in diesem Fall dieselbe ist), sondern auch aus der Interpretationsphase vor der Ausführung. Beide Phasen müssen bei einem Geschwindigkeitsvergleich berücksichtigt werden.

Glücklicherweise hat Perl ein praktisches Benchmark-Modul, mit dem wir einen Benchmark wie folgt implementieren können:

#!/usr/bin/perl -w

use Benchmark qw( cmpthese );

sub t_for   { eval 'die; for (;;) { }'; }
sub t_for2  { eval 'die; for (;;)  { }'; }
sub t_while { eval 'die; while (1) { }'; }

cmpthese(-60, { for => \&t_for, for2 => \&t_for2, while => \&t_while });

Beachten Sie, dass ich zwei verschiedene Versionen der Endlosschleife für for teste: eine, die kürzer als die while-Schleife ist, und eine andere, die zusätzlichen Platz hat, damit sie dieselbe Länge wie die while-Schleife hat.

Unter Ubuntu 11.04 x86_64 mit Perl 5.10.1 erhalte ich folgende Ergebnisse:

          Rate für für 2 während
für 100588 / s - -0% -2%
für 2 100937 / s 0% - -1%
während 102147 / s 2% 1% -

Die while-Schleife ist eindeutig der Gewinner auf dieser Plattform.

Unter FreeBSD 8.2 x86_64 mit Perl 5.14.1:

         Rate für für 2 während
für 53453 / s - -0% -2%
for2 53552 / s 0% - -2%
während 54564 / s 2% 2% -

While-Schleife ist auch hier der Gewinner.

Auf FreeBSD 8.2 i386 mit Perl 5.14.1:

         Bewerten Sie während für for2
während 24311 / s - -1% -1%
für 24481 / s 1% - -1%
für2 24637 / s 1% 1% -

Überraschenderweise ist die for-Schleife mit zusätzlichem Leerzeichen hier die schnellste Wahl!

Mein Fazit ist, dass die while-Schleife auf der x86_64-Plattform verwendet werden sollte, wenn der Programmierer die Geschwindigkeit optimiert. Offensichtlich sollte bei der Raumoptimierung eine for-Schleife verwendet werden. Meine Ergebnisse sind in Bezug auf andere Plattformen leider nicht schlüssig.

einrasten
quelle
9
Die Schlussfolgerung ist offensichtlich falsch. Benchmarkhat seine Grenzen und kann nicht verwendet werden, um schnell von langsam zu unterscheiden, wenn die Ergebnisse innerhalb von 7% voneinander liegen. Darüber hinaus haben Sie den Unterschied zwischen der forund der whileSchleife nicht getestet, da jedes Sub dievor Erreichen der Schleifen selbst wird. Und seit wann war die Menge an Leerzeichen für den Perl-Interpreter von Bedeutung? Sorry, aber die Analyse ist extrem fehlerhaft.
Zaid
2
@Zaid, Danke für deine Kommentare! Würde es Ihnen etwas ausmachen, Ihre eigene Antwort zu veröffentlichen, damit jeder daraus lernen kann? :) Das diesteht in meinem Code, weil ich nur den Unterschied in der Kompilierungszeit testen möchte . Wie andere bereits darauf hingewiesen haben, ist der resultierende Bytecode identisch, daher macht es keinen Sinn, dies zu testen. Überraschenderweise scheint die Menge an Leerraum in meinen Testumgebungen in diesem Fall einen kleinen Unterschied zu machen. Es könnte etwas damit zu tun haben, wie die Charaktere im Speicher ausgerichtet werden oder ähnliches ...
Snap
4
Ich muss keine Antwort posten, da das, was ich sagen würde, bereits von bdonlan erwähnt wurde. Und selbst wenn Sie die Kompilierungszeiten vergleichen, sind die Zahlen Benchmarknicht eindeutig. Vertraue diesem Unterschied von 1% überhaupt nicht!
Zaid
Nur 60 Iterationen? Führen Sie Tests etwa 5 Minuten lang durch, um genauere relative Zeiten zu erhalten.
Mooing Duck
-60führt den Test 60 Sekunden lang aus.
Snap
2

Theoretisch könnte ein völlig naiver Compiler das Literal '1' in der Binärdatei speichern (Speicherplatz verschwenden) und prüfen, ob bei jeder Iteration 1 == 0 ist (Zeitverschwendung und mehr Speicherplatz).

In der Realität werden Compiler jedoch auch ohne "keine" Optimierungen beide auf das Gleiche reduzieren. Sie können auch Warnungen ausgeben, da dies auf einen logischen Fehler hinweisen kann. Zum Beispiel könnte das Argument von whilewoanders definiert werden und Sie erkennen nicht, dass es konstant ist.

Nick T.
quelle
2

Ich bin überrascht, dass niemand die direktere Form angeboten hat, die der gewünschten Baugruppe entspricht:

forever:
     do stuff;
     goto forever;
Phil Miller
quelle
Dosis, die nicht den gleichen Maschinencode wie 1 oder für (;;) in say c hat?
Copas
1
Ein weiteres Manko dieses Ansatzes: Er verletzt die Kapselung, indem er die Schleife nicht in einen Block einschließt. Daher sind alle in der Schleife deklarierten Variablen außerhalb der Schleife verfügbar. (Natürlich könnten Sie { forever: do stuff; goto forever; })
Roy Tinker
2

while(1)ist eine Redewendung, for(;;)die von den meisten Compilern erkannt wird.

Ich war froh zu sehen, dass Perl auch erkennt until(0).

JMD
quelle
In welcher Situation wäre bis (0) hilfreich?
Copas
3
bis () ist das Gegenteil von while (), genauso wie wenn () das Gegenteil von if () ist. Wie überall in diesem Thread vorgeschlagen, könnte man schreiben: {etwas ...} tun, während (! Bedingung) Eine Alternative könnte sein, bis (Bedingung) {etwas}
JMD
2

Um die for (;;)vs- while (1)Debatte zusammenzufassen: Es ist offensichtlich, dass erstere in den Tagen älterer, nicht optimierender Compiler schneller war. Aus diesem Grund wird sie in älteren Codebasen wie Lions Unix-Quellcodekommentaren verwendet, jedoch im Zeitalter der Badass-Optimierung Compiler diese Gewinne sind weggekoppelt, da ich der Meinung bin, dass letzteres leichter zu verstehen ist als erstere.

redbandit
quelle
2

Bin gerade auf diesen Thread gestoßen (obwohl einige Jahre zu spät).

Ich glaube, ich habe den eigentlichen Grund gefunden, warum "for (;;)" besser ist als "while (1)".

gemäß dem "Barr Coding Standard 2018"

Kernighan & Ritchie long ago recommended for (;;) , which has the additional benefit
of insuring against the visually-confusing defect of a while (l); referencing a variable l’.

Im Grunde ist dies kein Geschwindigkeitsproblem, sondern ein Problem der Lesbarkeit. Abhängig von der Schriftart / dem Druck des Codes kann die Nummer eins (1) in einer Weile wie ein Kleinbuchstabe l aussehen.

dh 1 vs l. (In einigen Schriftarten sehen diese identisch aus).

Während (1) wie eine while-Schleife aussehen kann, die vom variablen Buchstaben L abhängt.

while (true) funktioniert möglicherweise auch, aber in einigen älteren C- und eingebetteten C-Fällen sind true / false noch nicht definiert, es sei denn, stdbool.h ist enthalten.

Nick Law
quelle
2
Ich würde sagen, das Problem in Ihrem Code wäre, dass Sie eine Variable mit dem Namen haben l, nicht diese, 1und lähnlich aussehen können.
Mjuopperi
Ich bin damit einverstanden, dass der Barr-Codierungsstandard auch an anderer Stelle besagt, dass Variablen auch in for-Schleifen mindestens 3 Zeichen lang sein müssen. dh kein i ++ etc. in einer for-Schleife. Ich neige dazu zu denken, dass das ein bisschen viel sein kann. Während der Eingabe fällt mir auch auf, dass nicht nur der Buchstabe L wie eine 1 aussieht. Der Buchstabe i, der üblicherweise als Variable verwendet wird, kann ebenfalls Probleme verursachen.
Nick Law
-3

Ich würde denken, dass beide in Bezug auf die Leistung gleich sind. Ich würde zwar while (1) für die Lesbarkeit bevorzugen, aber ich frage mich, warum Sie eine Endlosschleife benötigen.

bichonfrise74
quelle
-14

Sie sind gleich. Es gibt viel wichtigere Fragen zum Nachdenken.


Mein Punkt, der oben impliziert, aber nicht explizit gemacht wurde, ist, dass ein anständiger Compiler für beide Schleifenformen genau den gleichen Code generieren würde. Der größere Punkt ist, dass das Schleifenkonstrukt einen kleinen Teil der Laufzeit eines Algorithmus ausmacht und Sie zunächst sicherstellen müssen, dass Sie den Algorithmus und alles andere, was damit zusammenhängt, optimiert haben. Die Optimierung Ihres Schleifenkonstrukts sollte unbedingt ganz unten auf Ihrer Prioritätenliste stehen.

Mark Ransom
quelle
22
Keine Links oder Erklärungen. Nicht hilfreich, subjektiv und ein wenig herablassend.
CDMckay
1
Nun, kein Beweis, aber er hat recht. Beide nennen den Opcode zum Springen, wenn er falsch ist. (was es genauso machen würde wie goto, aber niemand mag gotos)
Matthew Whited
3
Mir war nicht bewusst, dass nur wichtige Fragen gestellt werden sollten, mein Fehler war meine erste Frage.
Copas
3
Ja, ich gebe zu, es ist herablassend. Aber im Ernst, auch ohne Beweise ist es offensichtlich, dass sie sich schnell im selben Stadion befinden werden; Wenn es um Stil ging, gab es etwas zu streiten. Ich habe versucht, darauf hinzuweisen, dass dies auf der Liste der Dinge, über die man sich Sorgen machen muss, wirklich ganz unten auf der Liste stehen sollte.
Mark Ransom
8
Ich habe nicht versucht, ein Idiot zu sein. Ich habe versucht, einen Punkt zu machen. Als ich es gepostet habe, habe ich versucht, eine Art dunklen Humor zu finden, und es ist offensichtlich, dass ich versagt habe. dafür entschuldige ich mich.
Mark Ransom