it-swarm.com.de

Was ist schneller: während (1) oder während (2)?

Dies war eine Interviewfrage, die von einem Senior Manager gestellt wurde.

Welche ist schneller? 

while(1) {
    // Some code
}

oder 

while(2) {
    //Some code
}

Ich sagte, dass beide die gleiche Ausführungsgeschwindigkeit haben, da der Ausdruck in while schließlich zu true oder false ausgewertet werden sollte. In diesem Fall werden beide zu true ausgewertet, und es gibt keine zusätzlichen bedingten Anweisungen in der while-Bedingung. Beide haben also die gleiche Ausführungsgeschwindigkeit und ich bevorzuge (1).

Aber der Interviewer sagte zuversichtlich: "Überprüfen Sie Ihre Grundlagen. while(1) ist schneller als while(2)."

Ist das wahr?

Siehe auch: Ist "for (;;)" schneller als "while (TRUE)"? Wenn nein, warum benutzen die Leute es?

570
Nikole

Beide Schleifen sind unendlich, aber wir können sehen, welche mehr Anweisungen/Ressourcen pro Iteration benötigt.

Mit gcc habe ich die beiden folgenden Programme für Assembly auf verschiedenen Optimierungsebenen kompiliert:

int main(void) {
    while(1) {}
    return 0;
}


int main(void) {
    while(2) {}
    return 0;
}

Auch ohne Optimierungen (-O0), die generierte Assembly war für beide Programme identisch . Daher gibt es keinen Geschwindigkeitsunterschied zwischen dem zwei Schleifen.

Als Referenz dient hier die generierte Assembly (unter Verwendung von gcc main.c -S -masm=intel Mit einem Optimierungsflag):

Mit -O0:

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    Push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 32
    .seh_stackalloc 32
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Mit -O1:

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    sub rsp, 40
    .seh_stackalloc 40
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Mit -O2 Und -O3 (Gleiche Ausgabe):

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .section    .text.startup,"x"
    .p2align 4,,15
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    sub rsp, 40
    .seh_stackalloc 40
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Tatsächlich ist die für die Schleife generierte Assembly für jede Optimierungsstufe identisch:

 .L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Die wichtigen Punkte sind:

.L2:
    jmp .L2

Ich kann Assembly nicht sehr gut lesen, aber dies ist offensichtlich eine bedingungslose Schleife. Die Anweisung jmp setzt das Programm bedingungslos auf das Label .L2 Zurück, ohne einen Wert mit true zu vergleichen, und tut dies natürlich sofort wieder, bis das Programm irgendwie beendet ist. Dies entspricht direkt dem C/C++ Code:

L2:
    goto L2;

Bearbeiten:

Interessanterweise haben auch mit keine Optimierungen die folgenden Schleifen in Assembly alle genau die gleiche Ausgabe erzeugt (unbedingte jmp):

while(42) {}

while(1==1) {}

while(2==2) {}

while(4<7) {}

while(3==3 && 4==4) {}

while(8-9 < 0) {}

while(4.3 * 3e4 >= 2 << 6) {}

while(-0.1 + 02) {}

Und sogar zu meinem Erstaunen:

#include<math.h>

while(sqrt(7)) {}

while(hypot(3,4)) {}

Mit benutzerdefinierten Funktionen wird es ein bisschen interessanter:

int x(void) {
    return 1;
}

while(x()) {}


#include<math.h>

double x(void) {
    return sqrt(7);
}

while(x()) {}

Bei -O0 Rufen diese beiden Beispiele tatsächlich x auf und führen für jede Iteration einen Vergleich durch.

Erstes Beispiel (Rückgabe 1):

.L4:
    call    x
    testl   %eax, %eax
    jne .L4
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Zweites Beispiel (sqrt(7) zurückgeben):

.L4:
    call    x
    xorpd   %xmm1, %xmm1
    ucomisd %xmm1, %xmm0
    jp  .L4
    xorpd   %xmm1, %xmm1
    ucomisd %xmm1, %xmm0
    jne .L4
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Ab -O1 Wird jedoch dieselbe Assembly wie in den vorherigen Beispielen erstellt (ein unbedingter jmp zurück zum vorherigen Label).

TL; DR

Unter GCC werden die verschiedenen Schleifen zu identischen Assemblys kompiliert. Der Compiler wertet die konstanten Werte aus und macht sich nicht die Mühe, einen tatsächlichen Vergleich durchzuführen.

Die Moral der Geschichte lautet:

  • Es gibt eine Übersetzungsschicht zwischen C++ - Quellcode und CPU-Anweisungen, und diese Schicht hat wichtige Auswirkungen auf die Leistung.
  • Daher kann die Leistung nicht nur anhand des Quellcodes bewertet werden.
  • Der Compiler sollte intelligent genug sein, um solche trivialen Fälle zu optimieren. Programmierer sollten in den allermeisten Fällen nicht ihre Zeit damit verschwenden, über sie nachzudenken.

Ja, while(1) ist viel schneller als while(2), für einen Menschen zum Lesen! Wenn ich while(1) in einer unbekannten Codebasis sehe, weiß ich sofort, was der Autor beabsichtigt hat, und meine Augäpfel können in die nächste Zeile übergehen.

Wenn ich while(2) sehe, werde ich wahrscheinlich in meinen Tracks stehen bleiben und versuchen herauszufinden, warum der Autor while(1) nicht geschrieben hat. Ist der Finger des Autors auf der Tastatur verrutscht? Verwenden die Betreuer dieser Codebase while(n) als obskuren Mechanismus, um Schleifen anders aussehen zu lassen? Ist es eine grobe Lösung für eine falsche Warnung in einem defekten statischen Analysewerkzeug? Oder ist das ein Hinweis, dass ich generierten Code lese? Ist es ein Fehler, der aus einem schlecht beratenen Finden und Ersetzen aller oder aus einer schlechten Verschmelzung oder einem kosmischen Strahl resultiert? Vielleicht soll diese Codezeile etwas ganz anderes machen. Vielleicht sollte es while(w) oder while(x2) lesen. Ich finde den Autor besser in der Geschichte der Datei und sende ihnen eine "WTF" E-Mail ... und jetzt habe ich meinen geistigen Kontext gebrochen. Die while(2) könnte einige Minuten meiner Zeit in Anspruch nehmen, wenn while(1) einen Bruchteil einer Sekunde gebraucht hätte!

Ich übertreibe, aber nur ein bisschen. Die Lesbarkeit des Codes ist sehr wichtig. Und das ist erwähnenswert in einem Interview!

263
Chris Culter

Die vorhandenen Antworten, die den Code zeigen, der von einem bestimmten Compiler für ein bestimmtes Ziel mit einem bestimmten Satz von Optionen generiert wurde, beantworten die Frage nicht vollständig - es sei denn, die Frage wurde in diesem speziellen Kontext gestellt mit Standardoptionen? ", zum Beispiel).

Bezüglich der Sprachdefinition wertet in abstract machinewhile (1) die Ganzzahlkonstante 1 und while (2) die Ganzzahlkonstante 2 aus; In beiden Fällen wird das Ergebnis auf Null verglichen. Der Sprachstandard sagt absolut nichts über die relative Leistung der beiden Konstrukte aus.

Ich kann mir vorstellen, dass ein extrem naiver Compiler möglicherweise unterschiedlichen Maschinencode für die beiden Formulare generiert, zumindest wenn er kompiliert wird, ohne eine Optimierung anzufordern.

Andererseits müssen C-Compiler unbedingt some konstante Ausdrücke zur Kompilierungszeit auswerten, wenn sie in Kontexten auftreten, die einen konstanten Ausdruck erfordern. Zum Beispiel das:

int n = 4;
switch (n) {
    case 2+2: break;
    case 4:   break;
}

erfordert eine Diagnose; Ein fauler Compiler hat nicht die Möglichkeit, die Auswertung von 2+2 bis zur Ausführungszeit aufzuschieben. Da ein Compiler zur Kompilierungszeit konstante Ausdrücke auswerten kann, gibt es keinen guten Grund, diese Funktion nicht zu nutzen, auch wenn sie nicht benötigt wird.

Der C-Standard ( N157 6.8.5p4) besagt das

Eine Iterationsanweisung bewirkt, dass eine Anweisung mit dem Namen Schleifenkörper wiederholt ausgeführt wird, bis der Steuerausdruck mit 0 verglichen wird.

Die relevanten konstanten Ausdrücke sind also 1 == 0 und 2 == 0, die beide den int -Wert 0 ergeben. (Dieser Vergleich ist in der Semantik der while -Schleife implizit enthalten; sie existieren nicht als tatsächliche C-Ausdrücke.)

Ein pervers naiver Compiler könnte unterschiedlichen Code für die beiden Konstrukte generieren. Zum Beispiel könnte es zum einen eine bedingungslose Endlosschleife erzeugen (wobei 1 als Sonderfall behandelt wird) und zum anderen könnte es einen expliziten Laufzeitvergleich erzeugen, der 2 != 0 entspricht. Aber ich bin noch nie auf einen C-Compiler gestoßen, der sich tatsächlich so verhält, und ich bezweifle ernsthaft, dass es einen solchen Compiler gibt.

Die meisten Compiler (ich bin versucht zu sagen, alle Compiler mit Produktionsqualität) haben die Möglichkeit, zusätzliche Optimierungen anzufordern. Bei einer solchen Option ist es sogar noch unwahrscheinlicher, dass ein Compiler unterschiedlichen Code für die beiden Formulare generiert.

Wenn Ihr Compiler für die beiden Konstrukte unterschiedlichen Code generiert, überprüfen Sie zunächst, ob die unterschiedlichen Codesequenzen tatsächlich eine unterschiedliche Leistung aufweisen. Wenn dies der Fall ist, versuchen Sie es erneut mit einer Optimierungsoption (falls verfügbar). Wenn sie sich immer noch unterscheiden, senden Sie einen Fehlerbericht an den Compiler-Hersteller. Es ist kein (notwendiger) Fehler im Sinne einer Nichteinhaltung des C-Standards, aber es ist mit ziemlicher Sicherheit ein Problem, das behoben werden sollte.

Fazit: while (1) und while(2)fast ​​haben mit Sicherheit die gleiche Leistung. Sie haben genau die gleiche Semantik, und es gibt keinen guten Grund für einen Compiler, keinen identischen Code zu generieren.

Und obwohl es für einen Compiler vollkommen legal ist, schnelleren Code für while(1) als für while(2) zu generieren, ist es für einen Compiler ebenso legal, schnelleren Code für while(1) als für ein anderes Vorkommen von zu generieren while(1) im selben Programm.

(In der von Ihnen gestellten Frage ist eine weitere implizite Frage enthalten: Wie gehen Sie mit einem Interviewer um, der auf einem falschen technischen Punkt besteht. Dies wäre wahrscheinlich eine gute Frage für die Workplace-Site ).

151
Keith Thompson

Warte eine Minute. Der Interviewer, sah er aus wie dieser Typ?

enter image description here

Es ist schon schlimm genug, dass der Interviewer selbst dieses Interview nicht bestanden hat . Was ist, wenn andere Programmierer dieser Firma diesen Test "bestanden" haben?

Bewertung der Aussagen 1 == 0 und 2 == 0 sollte gleich schnell sein . Wir könnten uns schlechte Compiler-Implementierungen vorstellen, bei denen einer schneller sein könnte als der andere. Aber es gibt keinen guten Grund, warum einer schneller sein sollte als der andere.

Selbst wenn es obskure Umstände gibt, unter denen die Behauptung wahr wäre, sollten Programmierer nicht auf der Grundlage von Kenntnissen über obskure (und in diesem Fall gruselige) Trivia bewertet werden. Mach dir keine Sorgen um dieses Interview, der beste Schritt hier ist wegzugehen.

Haftungsausschluss: Dies ist KEIN Original-Dilbert-Cartoon. Dies ist nur ein Mashup .

137
janos

Deine Erklärung ist richtig. Dies scheint eine Frage zu sein, die neben dem technischen Wissen Ihr Selbstbewusstsein überprüft.

Übrigens, wenn Sie geantwortet haben

Beide Codeteile sind gleich schnell, da beide unendlich viel Zeit in Anspruch nehmen

der Interviewer würde sagen

while (1) kann jedoch mehr Iterationen pro Sekunde ausführen. kannst du erklären warum? (das ist Quatsch; teste dein Vertrauen erneut)

Indem Sie wie auf diese Frage geantwortet haben, haben Sie Zeit gespart, die Sie sonst bei der Diskussion dieser schlechten Frage verlieren würden.


Hier ist ein Beispielcode, der vom Compiler auf meinem System (MS Visual Studio 2012) mit deaktivierten Optimierungen generiert wurde:

yyy:
    xor eax, eax
    cmp eax, 1     (or 2, depending on your code)
    je xxx
    jmp yyy
xxx:
    ...

Bei aktivierten Optimierungen:

xxx:
    jmp xxx

Der generierte Code ist also zumindest bei einem optimierenden Compiler identisch.

75
anatolyg

Die wahrscheinlichste Erklärung für die Frage ist, dass der Interviewer der Meinung ist, dass der Prozessor die einzelnen Bits der Zahlen nacheinander prüft, bis er einen Wert ungleich Null erreicht:

1 = 00000001
2 = 00000010

Wenn das "Null ist?" Wenn der Algorithmus von der rechten Seite der Zahl aus startet und jedes Bit prüfen muss, bis ein Bit ungleich Null erreicht ist, müsste die while(1) { }-Schleife doppelt so viele Bits pro Iteration prüfen wie die while(2) { }-Schleife.

Dies erfordert ein sehr falsches Denkmodell für die Funktionsweise von Computern, hat jedoch eine eigene interne Logik. Eine Möglichkeit zu prüfen wäre, zu fragen, ob while(-1) { } oder while(3) { } gleich schnell wäre oder ob while(32) { } noch langsamer wäre.

58
Ryan Cavanaugh

Natürlich kenne ich die wahren Absichten dieses Managers nicht, aber ich schlage eine völlig andere Sichtweise vor: Wenn ein neues Mitglied in ein Team aufgenommen wird, ist es hilfreich zu wissen, wie er auf Konfliktsituationen reagiert.

Sie trieben dich in einen Konflikt. Wenn das stimmt, sind sie schlau und die Frage war gut. In einigen Branchen, wie z. B. dem Bankwesen, kann die Veröffentlichung Ihres Problems bei Stack Overflow ein Grund für die Ablehnung sein.

Aber ich weiß es natürlich nicht, ich schlage nur eine Option vor.

32
Tõnu Samuel

Ich denke, der Hinweis ist in "von einem Senior Manager gefragt" zu finden. Diese Person hörte offensichtlich mit dem Programmieren auf, als er Manager wurde, und dann dauerte es mehrere Jahre, um ein Senior Manager zu werden. Nie verlor das Interesse an der Programmierung, schrieb aber seitdem keine Zeile. Daher ist seine Referenz nicht "irgendein anständiger Compiler da draußen", wie in einigen Antworten erwähnt wird, sondern "der Compiler, mit dem diese Person vor 20 bis 30 Jahren gearbeitet hat". 

Zu dieser Zeit hatten Programmierer einen erheblichen Teil ihrer Zeit damit verbracht, verschiedene Methoden auszuprobieren, um ihren Code schneller und effizienter zu machen, da die CPU-Zeit des 'zentralen Minicomputers' so wertvoll war. So wie die Leute Compiler geschrieben haben. Ich vermute, dass der einzige Compiler, den sein Unternehmen damals zur Verfügung stellte, auf der Grundlage von "häufig anzutreffenden Anweisungen, die optimiert werden können" zur Verfügung stand und bei einer Weile eine Abkürzung nahm (1) und alles auswertete sonst, einschließlich einer Weile (2). Wenn Sie solch eine Erfahrung gemacht haben, können Sie seine Position und sein Vertrauen darin erklären. 

Der beste Ansatz, um Sie einzustellen, ist wahrscheinlich eine, die es dem Senior Manager ermöglicht, sich hinreißen zu lassen und Sie 2-3 Minuten über "die guten alten Tage des Programmierens" zu unterrichten, bevor SIE reibungslos ihn zum nächsten Interview-Thema führen. (Ein gutes Timing ist hier wichtig - zu schnell und Sie unterbrechen die Geschichte - zu langsam und werden als jemand mit unzureichendem Fokus bezeichnet). Sagen Sie ihm am Ende des Interviews, dass Sie sehr daran interessiert wären, mehr über dieses Thema zu erfahren. 

25
OldFrank

Sie hätten ihn fragen sollen, wie er zu dieser Schlussfolgerung gekommen ist. Unter jedem anständigen Compiler da draußen kompilieren die beiden zu den gleichen asm-Anweisungen. Also hätte er Ihnen auch den Compiler sagen sollen, um loszulegen. Trotzdem müssten Sie den Compiler und die Plattform sehr gut kennen, um eine theoretisch fundierte Vermutung zu erstellen. Am Ende spielt es in der Praxis keine Rolle, da es andere externe Faktoren wie Speicherfragmentierung oder Systemlast gibt, die die Schleife stärker beeinflussen als dieses Detail.

19
Valentin Radu

Um dieser Frage willen, sollte ich hinzufügen, dass ich mich an Doug Gwyn vom C-Ausschuss erinnere, der schrieb, dass einige frühe C-Compiler ohne den Optimierer-Pass einen Test in Assembly für die while(1) erzeugen würden (im Vergleich zu for(;;), das dies nicht hätte).

Ich würde dem Interviewer mit dieser historischen Anmerkung antworten und dann sagen, dass ein Compiler, selbst wenn ich sehr überrascht wäre, dass ein Compiler dies getan hätte, Folgendes hätte:

  • ohne Optimierer übergeben den Compiler einen Test für while(1) und while(2)
  • mit dem Optimiererpass wird der Compiler angewiesen, alle while(1) (mit einem unbedingten Sprung) zu optimieren, da sie als idiomatisch betrachtet werden. Dies würde die while(2) mit einem Test verlassen und macht daher einen Leistungsunterschied zwischen den beiden.

Ich würde dem Interviewer natürlich hinzufügen, dass das gleiche Konstrukt, wenn man while(1) und while(2) nicht berücksichtigt, ein Zeichen für die Optimierung von geringer Qualität ist, da es sich um äquivalente Konstrukte handelt.

18
ouah

Eine andere Frage zu einer solchen Frage wäre, zu sehen, ob Sie den Mut hatten, Ihrem Manager mitzuteilen, dass er/sie falsch liegt! Und wie leise kannst du es kommunizieren. 

Mein erster Instinkt wäre gewesen, eine Assembly-Ausgabe zu generieren, um dem Manager zu zeigen, dass ein anständiger Compiler sich darum kümmern sollte.

9
UncleKing

Um zu sehen, wie viele Menschen in dieses Problem eintauchen, zeigt dies genau, warum dies ein Test sein könnte, um zu sehen, wie schnell Sie Mikrooptimierung Dinge wollen.

Meine Antwort wäre: Es ist nicht so wichtig, ich konzentriere mich eher auf das Geschäftsproblem, das wir lösen. Schließlich werde ich dafür bezahlt.

Darüber hinaus würde ich mich für while(1) {} entscheiden, weil dies häufiger vorkommt und andere Teammitglieder keine Zeit benötigen, um herauszufinden, warum jemand eine höhere Zahl als 1 anstrebt.

Jetzt schreiben Sie etwas Code. ;-)

8
Bart Verkoeijen

Es scheint mir, dass dies eine dieser Verhaltensinterviews ist, die als technische Frage maskiert werden. Einige Unternehmen tun dies - sie werden eine technische Frage stellen, die für einen kompetenten Programmierer relativ einfach zu beantworten sein sollte. Wenn der Interviewpartner jedoch die richtige Antwort gibt, wird er vom Interviewer darauf hingewiesen, dass sie falsch liegen.

Das Unternehmen möchte wissen, wie Sie in dieser Situation reagieren werden. Sitzen Sie ruhig da und drängen Sie nicht darauf, dass Ihre Antwort richtig ist, entweder aus Selbstzweifel oder aus Angst, den Interviewer zu stören? Oder sind Sie bereit, eine Person herauszufordern, von der Sie wissen, dass sie falsch ist? Sie möchten sehen, ob Sie bereit sind, sich für Ihre Überzeugungen einzusetzen, und ob Sie dies taktvoll und respektvoll tun können.

4
pacoverflow

Wenn Sie sich Sorgen um die Optimierung machen, sollten Sie dies nutzen

for (;;)

denn das hat keine tests. (zynischer Modus)

4
Tom Tanner

Ich programmierte C- und Assembly-Code zurück, wenn dieser Unsinn einen Unterschied gemacht hatte. Wenn es einen Unterschied machte, haben wir es in Assembly geschrieben.

Wenn ich diese Frage hätte, hätte ich Donald Knuths berühmtes Zitat von 1974 über vorzeitige Optimierung wiederholt und wäre gelaufen, wenn der Interviewer nicht gelacht hätte und weitergegangen wäre.

3
Peter Wooster

Vielleicht hat der Interviewer diese dumme Frage absichtlich gestellt und wollte, dass Sie 3 Punkte machen:

  1. Grundlegendes. Beide Loops sind unendlich, es ist schwer über Performance zu reden.
  2. Wissen über Optimierungsstufen. Er wollte von Ihnen hören, wenn Sie zulassen, dass der Compiler eine Optimierung für Sie vornimmt, dies würde die Bedingung optimieren, insbesondere wenn der Block nicht leer ist.
  3. Wissen über die Mikroprozessorarchitektur. Die meisten Architekturen verfügen über eine spezielle CPU-Anweisung zum Vergleich mit 0 (nicht unbedingt schneller). 
3
Rok Kralj

Sie sind beide gleich - gleich.

Laut den Spezifikationen wird alles, was nicht 0 ist, als wahr betrachtet, also auch ohne Optimierung. Ein guter Compiler generiert keinen Code .__ für while (1) oder while (2). Der Compiler würde eine einfache Überprüfung für != 0 erzeugen.

2

Hier ist ein Problem: Wenn Sie tatsächlich ein Programm schreiben und dessen Geschwindigkeit messen, kann die Geschwindigkeit beider Schleifen unterschiedlich sein! Für einen vernünftigen Vergleich: 

unsigned long i = 0;
while (1) { if (++i == 1000000000) break; }

unsigned long i = 0;
while (2) { if (++i == 1000000000) break; }

wenn ein Code hinzugefügt wird, der die Zeit druckt, kann ein zufälliger Effekt, z. B. wie sich die Schleife in einer oder zwei Cache-Zeilen befindet, einen Unterschied machen. Eine Schleife kann zufällig vollständig in einer Cachezeile oder am Anfang einer Cachezeile liegen oder zwei Cachezeilen überspannen. Und das, was der Interviewer für am schnellsten hält, könnte tatsächlich am schnellsten sein - zufällig. 

Worst-Case-Szenario: Ein optimierender Compiler ermittelt nicht, was die Schleife tut, stellt jedoch fest, dass die Werte, die bei der Ausführung der zweiten Schleife erzeugt werden, dieselben sind wie die der ersten. Und generiere vollen Code für die erste Schleife, aber nicht für die zweite. 

2
gnasher729

Nach der Menge an Zeit und Mühe zu urteilen, haben die Menschen diese sehr einfache Frage getestet, geprüft und beantwortet. Id sagt, dass beide durch die Fragestellung sehr langsam wurden.

Und so noch mehr Zeit damit verbringen ...

"while (2)" ist lächerlich, weil

"while (1)" und "while (true)" werden historisch verwendet, um eine Endlosschleife zu erstellen, die erwartet, dass "break" zu einem bestimmten Zeitpunkt innerhalb der Schleife aufgerufen wird, basierend auf einer Bedingung, die sicherlich auftreten wird. 

Die "1" ist einfach dazu da, immer als wahr zu bewerten, und daher ist "while (2)" ungefähr so ​​dumm wie "while (1 + 1 == 2)", was ebenfalls als wahr bewertet wird.

Und wenn Sie völlig dumm sein wollen, verwenden Sie einfach: -

while (1 + 5 - 2 - (1 * 3) == 0.5 - 4 + ((9 * 2) / 4)) {
    if (succeed())
        break;
}

Ich würde gerne glauben, dass Ihr Codierer einen Tippfehler gemacht hat, der die Ausführung des Codes nicht beeinflusst hat. Wenn er jedoch absichtlich die "2" verwendet, nur um seltsam zu sein, dann sollten Sie ihn erst sacken, bevor er den Code in Ihrem Code durchdringt lesen und arbeiten mit.

2
ekerner

Das hängt vom Compiler ab.

Wenn der Code optimiert wird oder 1 und 2 mit der gleichen Anzahl von Anweisungen für einen bestimmten Befehlssatz als wahr ausgewertet werden, ist die Ausführungsgeschwindigkeit gleich.

In realen Fällen ist dies immer gleich schnell, aber es ist möglich, sich einen bestimmten Compiler und ein bestimmtes System vorzustellen, wenn dies anders bewertet wird.

Ich meine: das ist nicht wirklich eine Frage der Sprache (C).

1
user143522

Die naheliegende Antwort lautet: Wie veröffentlicht, würden beide Fragmente eine ebenso belebte Endlosschleife ausführen, was das Programm unendlich macht langsam .

Obwohl die Neudefinition von C-Schlüsselwörtern als Makros technisch undefiniertes Verhalten ergeben würde, ist es die einzige Möglichkeit, eines der beiden Codefragmente schnell zu machen.

#define while sleep

dies macht while(1) tatsächlich doppelt so schnell (oder halb so langsam) wie while(2)

0
chqrlie

Da die Leute, die diese Frage beantworten wollen, die schnellste Schleife wünschen, hätte ich geantwortet, dass beide zu demselben Assembly-Code kompilieren, wie in den anderen Antworten angegeben. Trotzdem können Sie dem Interviewer vorschlagen, indem Sie 'loop unrolling' verwenden. eine do {} while-Schleife anstelle der while-Schleife. 

Vorsichtig: Sie müssen sicherstellen, dass die Schleife mindestens immer einmal läuft .

Die Schleife sollte innen eine Unterbrechungsbedingung haben.

Auch für diese Art von Schleife würde ich persönlich die Verwendung von do {} while (42) vorziehen, da jede ganze Zahl außer 0 den Job erledigen würde.

0
Antonin GAVREL