podczas gdy (1) Vs. dla (;;) Czy istnieje różnica prędkości?

154

Długa wersja...

Pewien współpracownik zapewnił mnie dzisiaj po obejrzeniu mojego użycia while (1)w skrypcie Perla, który for (;;)jest szybszy. Argumentowałem, że powinny być takie same, mając nadzieję, że tłumacz zoptymalizuje wszelkie różnice. Skonfigurowałem skrypt, który będzie uruchamiał 1 000 000 000 dla iteracji pętli i tej samej liczby pętli while i rejestruje czas między nimi. Nie mogłem znaleźć żadnej znaczącej różnicy. Mój współpracownik powiedział, że profesor powiedział mu, że while (1)robi porównanie, 1 == 1a for (;;)nie. Powtórzyliśmy ten sam test przy 100-krotnej liczbie iteracji w C ++ i różnica była nieistotna. Był to jednak graficzny przykład tego, o ile szybciej można skompilować kod w porównaniu z językiem skryptowym.

Krótka wersja...

Czy jest jakiś powód, aby preferować a while (1)over a, for (;;)jeśli potrzebujesz nieskończonej pętli, z której chcesz się wyrwać?

Uwaga: jeśli nie wynika to jasno z pytania. To była czysto zabawna dyskusja akademicka między kilkoma przyjaciółmi. Zdaję sobie sprawę, że nie jest to super ważna koncepcja, nad którą wszyscy programiści powinni się męczyć. Dzięki za wszystkie świetne odpowiedzi. Ja (i jestem pewien, że inni) nauczyłem się kilku rzeczy z tej dyskusji.

Aktualizacja: Wspomniany wyżej współpracownik odniósł się do odpowiedzi poniżej.

Cytowany tutaj na wypadek, gdyby został zakopany.

Pochodzi od programisty zespołu AMD. Stwierdził, że programiści C (ludzie) nie zdają sobie sprawy, że ich kod jest nieefektywny. Powiedział jednak dzisiaj, że kompilatory gcc są bardzo dobre i pozbawiają ludzi takich jak on interes. Powiedział na przykład, i powiedział mi o while 1vs for(;;). Używam go teraz z przyzwyczajenia, ale gcc, a zwłaszcza interpretery, będą wykonywać tę samą operację (skok procesora) przez oba te dni, ponieważ są zoptymalizowane.

Copas
źródło
4
Jestem ciekawy. Po co nieskończona pętla w skrypcie Perla? Oczywiście nie programujesz sterownika ani elementu systemowego ... Infinite jest cichy długo :-)
Luc M
125
Która nieskończona pętla jest najszybsza? LOL ... "Mój nowy komputer jest tak szybki, że wykonuje nieskończoną pętlę w niecałą godzinę ..." ;-)
Arjan Einbu
8
Czy to profesor socjologii mu to powiedział? W dzisiejszych czasach kod, który wpisujesz, nie jest tym, co widzi komputer.
brian d foy
5
spodziewam się, że czas potrzebny na przetestowanie tego był znacznie dłuższy niż ilość czasu potencjalnie zaoszczędzonego dzięki wiedzy, który z nich jest szybszy, jeśli w ogóle. nawet jeśli amortyzujesz je przez oba okresy programowania.
Peter Recore
4
Dlaczego kompilator miałby kiedykolwiek wygenerować kod w celu wykonania testu, o którym wie, że nie ma żadnych skutków ubocznych i którego wynik kompilator już zna? To nie ma sensu.
David Schwartz

Odpowiedzi:

218

W perlu dają te same rozkazy:

$ 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

Podobnie w 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

Więc myślę, że odpowiedź brzmi: są takie same w wielu kompilatorach. Oczywiście w przypadku niektórych innych kompilatorów niekoniecznie tak musi być, ale jest szansa, że ​​kod wewnątrz pętli i tak będzie kilka tysięcy razy droższy niż sama pętla, więc kogo to obchodzi?

bdonlan
źródło
15
spróbuj z B :: Deparse, usuwanie nieskończonej pętli for zwraca pętlę while: P
Kent Fredric
27
„W perlu dają te same rozkazy” ... tak, ale co jest szybsze? :-)
Tin Man
6
Uwielbiam to, że gcc podstawiło put () zamiast printf (), ponieważ jest tylko jeden argument i dlatego nie ma nic do formatowania - szybciej i bezpieczniej! (gcc sprawdza również tagi formatujące na liście argumentów zmiennych.)
Lee D
@ The Tin Man: są równoważne, ponieważ komputer wykonuje dokładnie te same operacje: P
BlackBear
1
@snap, to nie jest „całkowicie” niepoprawne, skupia się tylko na kosztach czasu działania. Nie mogę sobie wyobrazić, jaka sytuacja spowodowałaby, że czas analizy nieskończonych pętli był kluczowym czynnikiem decydującym o szybkości działania programu
bdonlan
55

Używając GCC, oba wydają się kompilować do tego samego języka asemblera:

L2:
        jmp     L2
Martin Cote
źródło
20
Używanie GCC z opcją -S (asembluj, nie łącz)
Martin Cote
54

Nie ma powodu, aby preferować jedno nad drugim. I sądzę, że while(1)w szczególności while(true)są bardziej czytelne niż for(;;), ale to tylko moje preferencje.

Bill the Lizard
źródło
94
#define EVER ;; ponieważ (NIGDY) zawsze uważałem to za zabawne.
Tom
19
Co powiesz na #define ever (;;) forever;
Martin Cote
16
Oba wydają się bardziej czytelne z pozoru, ale staram się nie definiować nowych słów kluczowych dla mojego programisty (zwykle mnie), który mógłby podrapać się po głowie.
Bill the Lizard
13
@Martin to nie zadziała, ponieważ # define's nie jest zastępowane w tokenie i foreverjest to jego własny token.
Lily Chung,
2
„Staram się nie definiować nowych słów kluczowych dla mojej konserwacji” - gdyby tylko więcej ludzi przyjęło taką postawę, nie chwytałbym się tych wszystkich bezmyślnych i magicznych sztuczek za każdym razem, gdy się odwracam!
tchrist
31

Nie ma różnicy w stosunku do normy. 6.5.3 / 1 ma:

Oświadczenie za

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

jest równa

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

A 6.5.3 / 2 ma:

Można pominąć jeden lub oba warunek i wyrażenie. Brak warunku sprawia, że ​​domniemana klauzula while jest równoważna while (prawda).

Czyli zgodnie ze standardem C ++ kod:

for (;;);

jest dokładnie taki sam jak:

{
  while (true) {
    ;
    ;
  }
}
Richard Corden
źródło
4
Nie dotyczy to w ogóle wygenerowanego kodu ani wydajności. Norma określa tylko funkcjonalność. Oczywiście wydajność będzie taka sama.
Potatoswatter
1
Nie wierzę, że to prawda, że ​​różnica w wykonaniu narusza zasadę as-if. Gdyby tak było, kompilatory nie byłyby uprawnione do przyspieszania kodu zgodnie z regułą as-if, na przykład poprzez zmianę kolejności niezależnych instrukcji. W rzeczywistości kompilatory dokładnie to robią. Ale moja kopia standardu jest na górze.
Steve Jessop
28

Kompilator Visual C ++ używany do emitowania ostrzeżenia dla platformy

while (1) 

(wyrażenie stałe), ale nie dla

for (;;)

Z for (;;)tego powodu kontynuowałem praktykę preferowania , ale nie wiem, czy kompilator nadal to robi.

sean e
źródło
ostrzeżenie jest prawdopodobnie spowodowane tym, że użyłeś while (1) zamiast while (prawda)
jrharshath
16
prawda jest stałą. while (true) jest wyrażeniem stałym. Dla wszystkich zainteresowanych ostrzeżenie C4127 jest udokumentowane tutaj: msdn.microsoft.com/en-us/library/6t66728h(VS.80).aspx
sean e
Tak, ostrzeżenie jest nadal obecne zarówno dla 1, jak i prawdziwego. To jest powód, dla którego zawsze używam dla (;;)
Elviss Strazdins
26

for(;;) jest o jeden znak mniej do wpisania, jeśli chcesz iść w tym kierunku, aby zoptymalizować rzeczy.

Chris Bartow
źródło
21
Dobrze wiedzieć, jeśli chodzi o golfa. W przeciwnym razie kiepski powód, aby wybrać składnię.
Adam Bellaire
@AdamBellaire Terseness często zwiększa czytelność, powyżej pewnego progu umiejętności.
Vector Gorgoth
20

Turbo C z tymi starymi kompilatorami for(;;)skutkuje szybszym kodem while(1).

Dzisiaj kompilatory gcc, Visual C (chyba prawie wszystkie) optymalizują się dobrze, a procesory o częstotliwości 4,7 MHz są rzadko używane.

W tamtych czasach a for( i=10; i; i-- )było szybsze niż for( i=1; i <=10; i++ ), ponieważ porównanie iwynosi 0, powoduje warunkowy skok CPU-Zero-Flag. Flaga zera została zmodyfikowana podczas ostatniej operacji dekrementacji ( i-- ), nie jest potrzebna żadna dodatkowa operacja cmp.

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

a tutaj for(i=1; i<=10; i++)z dodatkowym cmpl:

    call    __printf_chk
    incl    %ebx
    cmpl    $11, %ebx
    jne     .L2
    movl    -4(%ebp), %ebx
    leave
Lutz L.
źródło
13

Dla wszystkich ludzi, którzy argumentują, że nie powinieneś używać indefinte while i sugerują głupie rzeczy, takie jak używanie otwartego goto (serio, ouch)

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

Tak naprawdę nie można go skutecznie przedstawić w żaden inny sposób. Nie bez utworzenia zmiennej wyjściowej i zrobienia czarnej magii, aby ją zsynchronizować.

Jeśli masz skłonność do składni bardziej goto-esque, użyj czegoś rozsądnego, co ogranicza zakres.

flow: { 

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

Ostatecznie szybkość nie jest taka ważna

Martwienie się o to, jak efektywne pod względem szybkości są różne konstrukcje pętli, jest ogromną stratą czasu. Przedwczesna optymalizacja na wskroś. Nie przychodzi mi do głowy żadna sytuacja, jaką kiedykolwiek widziałem, w której kod profilujący znalazłby wąskie gardła w moim wyborze konstrukcji pętli.

Ogólnie jest to jak pętla i co z pętli.

Powinieneś "zoptymalizować" pod kątem czytelności i zwięzłości oraz napisać wszystko, co najlepiej wyjaśni problem następnemu biednemu frajerowi, który znajdzie twój kod.

Jeśli używasz sztuczki „goto LABEL”, o której ktoś wspomniał, a ja muszę użyć twojego kodu, przygotuj się na spanie z jednym okiem otwartym, zwłaszcza jeśli robisz to więcej niż raz, ponieważ takie rzeczy tworzą okropny kod spaghetti.

Tylko dlatego, że można tworzyć spaghetti code nie znaczy, że powinniśmy

Kent Fredric
źródło
9

Stroustrup, TC ++ PL (wydanie trzecie), §6.1.1:

Ciekawa notacja for (;;)jest standardowym sposobem określenia nieskończonej pętli; można by to wymówić „na zawsze”. […] while (true)jest alternatywą.

Wolę for (;;).

Hans W.
źródło
9

Jeśli kompilator nie przeprowadza żadnej optymalizacji, for(;;)zawsze będzie szybszy niż while(true). Dzieje się tak, ponieważ instrukcja while oblicza warunek za każdym razem, ale instrukcja for jest bezwarunkowym skokiem. Ale jeśli kompilator zoptymalizuje przepływ sterowania, może wygenerować niektóre rozkazy. Możesz bardzo łatwo odczytać kod demontażu.

PS możesz napisać nieskończoną pętlę w ten sposób:

#define EVER ;;
  //...
  for (EVER) {
    //...
  }
silverbullettt
źródło
W dzisiejszych czasach nie powinno się NIGDY zastępować EVS (mowa nastolatków)! Poważnie, chociaż po prostu używam dla (;;) {}. Czytałem w Internecie dawno temu o różnicach między nimi (kiedy byłem młodszy i nie wiedziałem, że są takie same) i po prostu utknąłem w tym, co przeczytałem.
Bja
8

Słyszałem o tym kiedyś.

Pochodzi od programisty zespołu AMD. Stwierdził, że programiści C (ludzie) nie zdają sobie sprawy, że ich kod jest nieefektywny. Powiedział jednak dzisiaj, że kompilatory gcc są bardzo dobre i pozbawiają ludzi takich jak on interes. Powiedział na przykład, i powiedział mi o while 1vs for(;;). Używam go teraz z przyzwyczajenia, ale gcc, a zwłaszcza interpretery, będą wykonywać tę samą operację (skok procesora) przez oba te dni, ponieważ są zoptymalizowane.

Jimmie Clark
źródło
5

W zoptymalizowanej wersji skompilowanego języka nie powinno być między nimi zauważalnej różnicy. Żadne z nich nie powinno kończyć się przeprowadzaniem jakichkolwiek porównań w czasie wykonywania, po prostu wykonają kod pętli, dopóki ręcznie nie wyjdziesz z pętli (np. Za pomocą a break).

Charlie
źródło
3

Dziwię się, że nikt właściwie przetestowane for (;;)kontra while (1)Perl!

Ponieważ perl jest językiem interpretowanym, czas potrzebny na uruchomienie skryptu w Perlu składa się nie tylko z fazy wykonania (która w tym przypadku jest taka sama), ale także z fazy interpretacji przed wykonaniem. Przy porównywaniu prędkości należy wziąć pod uwagę obie te fazy.

Na szczęście perl ma wygodny moduł Benchmark, za pomocą którego możemy zaimplementować benchmark, taki jak:

#!/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 });

Zauważ, że testuję dwie różne wersje nieskończonej pętli for: jedną, która jest krótsza niż pętla while, i drugą, która ma dodatkową przestrzeń, aby uzyskać taką samą długość jak pętla while.

Na Ubuntu 11.04 x86_64 z perlem 5.10.1 otrzymuję następujące wyniki:

          Stawka za 2 chwilę
dla 100588 / s - -0% -2%
dla2 100937 / s 0% - -1%
podczas gdy 102147 / s 2% 1% -

Pętla while jest zdecydowanie zwycięzcą na tej platformie.

We FreeBSD 8.2 x86_64 z perlem 5.14.1:

         Stawka za 2 chwilę
dla 53453 / s - -0% -2%
dla2 53552 / s 0% - -2%
podczas gdy 54564 / s 2% 2% -

Podczas gdy pętla jest tutaj również zwycięzcą.

W FreeBSD 8.2 i386 z perl 5.14.1:

         Oceniaj za for2
podczas gdy 24311 / s - -1% -1%
dla 24481 / s 1% - -1%
dla2 24637 / s 1% 1% -

Zaskakujące jest, że pętla for z dodatkową przestrzenią jest tutaj najszybszym wyborem!

Mój wniosek jest taki, że pętla while powinna być używana na platformie x86_64, jeśli programista optymalizuje pod kątem szybkości. Oczywiście pętla for powinna być używana podczas optymalizacji przestrzeni. Moje wyniki są niestety niejednoznaczne w odniesieniu do innych platform.

kłapnięcie
źródło
9
Wniosek jest rażąco błędny. Benchmarkma swoje ograniczenia i nie można go użyć do odróżnienia szybkiego od wolnego, jeśli wyniki mieszczą się w granicach 7%. Co więcej, nie przetestowałeś różnicy między pętlami fori, whileponieważ każdy subwoofer będzie działał dieprzed osiągnięciem samych pętli. I od kiedy ilość białych znaków ma znaczenie dla interpretera Perla? Przepraszamy, ale analiza jest bardzo błędna.
Zaid
2
@Zaid, dzięki za komentarze! Czy możesz opublikować własną odpowiedź, aby każdy mógł się z niej uczyć? :) To diejest w moim kodzie, ponieważ moim zamiarem jest przetestowanie tylko różnicy czasu kompilacji . Jak inni już zauważyli, wynikowy kod bajtowy jest identyczny, więc nie ma sensu go testować. Zaskakująco ilość białej przestrzeni wydaje się mieć niewielką różnicę w tym przypadku w moich środowiskach testowych. Może to mieć coś wspólnego z tym, jak postacie zostaną wyrównane w pamięci lub coś podobnego ...
zatrzask
4
Nie muszę publikować odpowiedzi, ponieważ bdonlan wspomniał już o tym, co bym powiedział. Nawet jeśli porównujesz czasy kompilacji, liczby, Benchmarkktóre nie są rozstrzygające. W ogóle nie ufaj tej 1% różnicy!
Zaid
Tylko 60 iteracji? Uruchom testy przez około 5 minut, aby uzyskać dokładniejsze czasy względne.
Mooing Duck,
-60uruchamia test przez 60 sekund.
zatrzask
2

Teoretycznie całkowicie naiwny kompilator mógłby przechowywać dosłowne „1” w pliku binarnym (marnowanie miejsca) i sprawdzać, czy 1 == 0 w każdej iteracji (marnowanie czasu i więcej miejsca).

Jednak w rzeczywistości, nawet przy braku optymalizacji, kompilatory nadal będą redukować oba do tego samego. Mogą również emitować ostrzeżenia, ponieważ może to wskazywać na błąd logiczny. Na przykład argument whilemożna zdefiniować gdzie indziej i nie zdajesz sobie sprawy, że jest stały.

Nick T.
źródło
2

Dziwię się, że nikt nie zaproponował bardziej bezpośredniej formy, odpowiadającej żądanemu montażowi:

forever:
     do stuff;
     goto forever;
Phil Miller
źródło
Dawka, która nie kończy się tym samym kodem maszynowym, co podczas 1 lub (;;) w powiedzmy c?
Copas
1
Jeszcze jedna wada tego podejścia: narusza hermetyzację, nie zamykając pętli w bloku - w ten sposób wszelkie zmienne zadeklarowane w pętli są dostępne poza pętlą. (Oczywiście, że możesz { forever: do stuff; goto forever; })
Roy Tinker
2

while(1)to idiom for(;;)rozpoznawany przez większość kompilatorów.

Cieszyłem się, że Perl też to rozpoznaje until(0).

JMD
źródło
W jakiej sytuacji byłoby pomocne do (0)?
Copas
3
dopóki () jest przeciwieństwem while (), tak jak chyba, że ​​() jest przeciwieństwem if (). Jak sugerowano w tym wątku, można by napisać: zrób {coś ...}, podczas gdy (! Warunek) Alternatywą może być do (warunek) {coś}
JMD
2

Podsumowując debatę na temat for (;;)vs while (1), jest oczywiste, że ta pierwsza była szybsza w czasach starszych nieoptymalizujących kompilatorów, dlatego zwykle widzisz ją w starszych bazach kodu, takich jak komentarze do kodu źródłowego Lions Unix, jednak w dobie optymalizacji kompilatory te zyski są zoptymalizowane, łącząc to z faktem, że to drugie jest łatwiejsze do zrozumienia niż pierwsze, uważam, że byłoby bardziej korzystne.

redbandit
źródło
2

Właśnie natknąłem się na ten wątek (chociaż spóźniony o kilka lat).

Myślę, że znalazłem właściwy powód, dla którego „za (;;)” jest lepsze niż „podczas (1)”.

zgodnie ze „standardem kodowania barier 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’.

w zasadzie nie jest to problem z szybkością, ale z czytelnością. W zależności od czcionki / nadruku kodu numer jeden (1) może wyglądać jak mała litera l.

czyli 1 vs l. (w niektórych czcionkach wyglądają identycznie).

Więc while (1) może wyglądać jak pętla while zależna od litery zmiennej L.

while (true) może również działać, ale w niektórych starszych przypadkach C i embedded C true / false nie są jeszcze zdefiniowane, chyba że dołączono stdbool.h.

Nick Law
źródło
2
Powiedziałbym, że problem w twoim kodzie polega na tym, że masz zmienną o nazwie l, a nie to 1i lmoże wyglądać podobnie.
mjuopperi
Zgoda, wiem, że standard kodowania Barr mówi również gdzie indziej, że zmienne muszą mieć co najmniej 3 znaki, nawet w pętlach for. tzn. brak i ++ itp. w pętli for. Wydaje mi się jednak, że może to być trochę za dużo. Podczas pisania zauważam również, że nie tylko litera L wygląda jak 1. Litera i, która jest powszechnie używana jako zmienna, również może powodować problemy.
Nick Law
-3

Myślę, że oba są takie same pod względem wydajności. Ale wolałbym while (1) ze względu na czytelność, ale pytam, dlaczego potrzebujesz nieskończonej pętli.

bichonfrise74
źródło
-14

Oni są tacy sami. Jest dużo ważniejszych pytań do rozważenia.


Mój punkt widzenia, który został dorozumiany, ale nie został wyraźnie przedstawiony powyżej, jest taki, że przyzwoity kompilator wygenerowałby dokładnie ten sam kod dla obu form pętli. Większe jest to, że konstrukcja pętli jest mniejszą częścią czasu wykonywania dowolnego algorytmu i musisz najpierw upewnić się, że zoptymalizowałeś algorytm i wszystko inne z nim związane. Optymalizacja konstrukcji pętli absolutnie powinna znajdować się na dole listy priorytetów.

Mark Okup
źródło
22
Brak linków i wyjaśnień. Niepomocne, subiektywne i trochę protekcjonalne.
cdmckay
1
no nie ma dowodu, ale ma rację. Obaj wzywają kod operacyjny do skakania, gdy jest fałszywy. (co sprawiłoby, że byłby taki sam jak goto, ale nikt nie lubi goto)
Matthew Whited
3
Nie zdawałem sobie sprawy, że tylko ważne pytania, które mam zadać, mój błąd był moim pierwszym pytaniem.
Copas
3
Tak, przyznaję, że to protekcjonalne. Ale poważnie, nawet bez żadnego dowodu jest oczywiste, że szybko znajdą się na tym samym boisku; jeśli pytanie dotyczyło stylu, byłoby się o co spierać. Starałem się zaznaczyć, że na liście rzeczy, o które należy się martwić, powinno to naprawdę znajdować się na dole listy.
Mark Ransom
8
Nie próbowałem być palantem. Próbowałem coś powiedzieć. Kiedy to opublikowałem, próbowałem stworzyć coś w rodzaju czarnego humoru i jest oczywiste, że mi się nie udało; za to przepraszam.
Mark Ransom