Czy" for (;;) "jest szybsze niż"while (TRUE)"? Jeśli nie, to dlaczego ludzie go używają?

for (;;) {
    //Something to be done repeatedly
}

Widziałem tego rodzaju rzeczy używane często, ale myślę, że jest to raczej dziwne... Czy nie byłoby dużo jaśniej powiedzieć while(true), czy coś w tym stylu?

Zgaduję, że (jak to jest powodem, dla wielu programistów, aby uciekać się do szyfrowania kodu) jest to mały margines szybciej?

Dlaczego i czy naprawdę warto? Jeśli tak, to dlaczego nie zdefiniować tego w ten sposób:
#define while(true) for(;;)

Zobacz także: które jest szybsze: while (1) Czy while(2)?

Author: Community, 2010-04-10

20 answers

    Nie jest szybszy.
  1. jeśli naprawdę Ci zależy, skompiluj z wyjściem assemblera dla swojej platformy i zobacz.
  2. Nieważne. To nie ma znaczenia. Napisz swoje nieskończone pętle, jak chcesz.
 244
Author: Ben Zotto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:06:49

Wolę for(;;) z dwóch powodów.

Jednym z nich jest to, że niektóre Kompilatory wytwarzają ostrzeżenia na while(true) (coś w rodzaju "loop condition is constant"). Unikanie ostrzeżeń jest zawsze dobrą rzeczą do zrobienia.

Innym jest to, że myślę, że for(;;) jest jaśniejszy i bardziej wymowny. Chcę nieskończonej pętli. Dosłownie nie ma żadnego warunku, od niczego nie zależy. Chcę, żeby to trwało wiecznie, dopóki nie zrobię czegoś, żeby się z tego wyrwać.

Natomiast z while(true), Cóż, co prawda ma wspólnego z cokolwiek? Nie interesuje mnie zapętlanie, dopóki true nie stanie się false, czyli to, co ta forma dosłownie mówi (loop while true is true). Chcę tylko zapętlić pętlę.

I nie, nie ma absolutnie żadnej różnicy w wydajności.

 163
Author: jalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-07 14:52:31

Osobiście używam for (;;), ponieważ nie ma w nim żadnych liczb, to tylko słowo kluczowe. Wolę to while (true), while (1), while (42), while (!0) itd.itd.

 52
Author: ta.speot.is,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:10:39

Because of Dennis Ritchie

  • Zacząłem używać for (;;), ponieważ tak robi Dennis Ritchie w K & R, a ucząc się nowego języka zawsze staram się naśladować mądrych facetów.

  • Jest to idiomatyczne C / C++. Prawdopodobnie lepiej jest na dłuższą metę przyzwyczaić się do tego, jeśli planujesz robić wiele w przestrzeni C/C++.

  • Twój #define nie zadziała, ponieważ rzecz # define ' D musi wyglądać jak identyfikator C.

  • Wszystkie współczesne Kompilatory będą generować ten sam kod dla obu konstrukcji.

 47
Author: Mark Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-10 06:44:55

Na pewno nie jest szybszy w żadnym zdrowym kompilatorze. Oba zostaną zestawione w bezwarunkowe skoki. Wersja for jest łatwiejsza do wpisania (jak powiedział Neil) i będzie jasna, jeśli rozumiesz składnię pętli for.

Jeśli jesteście ciekawi, oto co daje mi gcc 4.4.1 dla x86. Oba używają instrukcji x86 JMP.

void while_infinite()
{
    while(1)
    {
    puts("while");
    }
}

void for_infinite()
{
    for(;;)
    {
    puts("for");
    }
}

Kompiluje do (w części):

.LC0:
.string "while"
.text
.globl while_infinite
    .type   while_infinite, @function
while_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
.L2:
    movl    $.LC0, (%esp)
    call    puts
    jmp .L2
    .size   while_infinite, .-while_infinite
    .section    .rodata
.LC1:
    .string "for"
    .text
.globl for_infinite
    .type   for_infinite, @function
for_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
.L5:
    movl    $.LC1, (%esp)
    call    puts
    jmp .L5
    .size   for_infinite, .-for_infinite
 45
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-12 13:06:05

Wolę for (;;) ponieważ jest najbardziej spójny w różnych językach C-podobnych.

W C++ while (true) jest w porządku, ale w C definiowanie true zależy od nagłówka, jednak TRUE jest również powszechnie używanym makrem. Jeśli używasz while (1), jest to poprawne w C i C++ oraz JavaScript, ale nie w Javie lub C#, które wymagają warunku pętli jako boolean, np. while (true) lub while (1 == 1). W PHP słowa kluczowe są niewrażliwe na wielkość liter, ale język preferuje wielkimi literami TRUE.

Jednak for (;;) jest zawsze całkowicie poprawne we wszystkich tych językach.

 40
Author: Boann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 10:54:14

Osobiście wolę idiom for (;;) (który kompiluje się do tego samego kodu co while (TRUE).

Użycie while (TRUE) może być bardziej czytelne w pewnym sensie, zdecydowałem się użyć idiomu for (;;), ponieważ wyróżnia się .

Konstrukcja pętli nieskończonej powinna być łatwo zauważona lub wywołana w kodzie i osobiście uważam, że styl for (;;) robi to nieco lepiej niż while (TRUE) Czy while (1).

Przypominam również, że niektóre Kompilatory wydają ostrzeżenia, gdy wyrażenie sterujące pętli while jest stałą. Nie sądzę, że zdarza się to zbyt często, ale tylko potencjał fałszywych ostrzeżeń wystarcza mi, aby chcieć tego uniknąć.

 21
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 23:16:09

Widziałem, że niektórzy wolą to, ponieważ mają # define gdzieś tak:

#define EVER ;;

Co pozwala na zapisanie tego:

for (EVER)
{
    /* blah */
}
 17
Author: rmeador,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:30:07

A co z (jeśli twój język go obsługuje):

start:
/* BLAH */
goto start;
 16
Author: bungle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 23:17:04

Nie ma różnicy w kodzie maszynowym, który jest generowany.

Jednak, aby zniweczyć trend, argumentowałbym, że forma while(TRUE) jest o wiele bardziej czytelna i intuicyjna niż for(;;), i że czytelność i jasność są o wiele ważniejszymi powodami wytycznych kodowania niż jakiekolwiek powody, które słyszałem dla podejścia for (;;) (wolę oprzeć moje wytyczne kodowania na solidnym rozumowaniu i/lub dowód skuteczności).

 12
Author: Jason Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:18:05

Nie tylko znany wzorzec, ale standardowy idiom w C (i C++)

 11
Author: James McLeod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:09:54
while(true)

Generuje ostrzeżenie za pomocą Visual Studio (warunek jest stały). Większość miejsc, w których pracowałem kompiluje Kompilacje produkcyjne z ostrzeżeniami jako błędami. Więc

for(;;)

Jest preferowane.

 11
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-10 05:49:41

Oba powinny być takie same, jeśli kod jest zoptymalizowany przez kompilator. Aby wyjaśnić, co mam na myśli przez optymalizację, oto przykładowy kod napisany w MSVC 10:

int x = 0;

while(true) // for(;;)
{
    x +=1;

    printf("%d", x);
}

Jeśli zbudujesz go w trybie debugowania (bez optymalizacji (/Od)) demontaż pokazuje wyraźną różnicę. Wewnątrz while znajdują się dodatkowe instrukcje dotyczące warunku true.

while(true)
00D313A5  mov         eax,1                //extra 
00D313AA  test        eax,eax              //extra
00D313AC  je          main+39h (0D313B9h)  //extra
    {
        x +=1;
00D313AE  mov         eax,dword ptr [x]  
00D313B1  add         eax,1  
00D313B4  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D313B7  jmp         main+25h (0D313A5h)  


for(;;)
    {
        x +=1;
00D213A5  mov         eax,dword ptr [x]  
00D213A8  add         eax,1  
00D213AB  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D213AE  jmp         main+25h (0D213A5h)  

Jeśli jednak zbudujesz kod w trybie Release (z domyślnym Maximize Speed (/O2) ), otrzymasz takie same wyniki dla obu. Obie pętle są zredukowane do jednej instrukcji skoku.

for(;;)
    {
        x +=1;
01291010  inc         esi  

        printf("%d", x);
    ...
    }
0129101C  jmp         main+10h (1291010h)  

    while(true)
    {
        x +=1;
00311010  inc         esi  

        printf("%d", x);
    ...
    }
0031101C  jmp         main+10h (311010h)  

Cokolwiek użyjesz nie ma znaczenia dla porządnego kompilatora z optymalizacją prędkości jest włączony.

 10
Author: SylvanBlack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-02 07:39:48

To kwestia osobistych preferencji, która droga jest szybsza. Osobiście jestem touchtypistą i nigdy nie patrzę na moją klawiaturę , podczas programowania-mogę dotknąć wszystkich 104 klawiszy na mojej klawiaturze.

Znajduję jeśli szybciej wpisać " while (TRUE)".

Mentalnie dodałem kilka pomiarów ruchu palców i zsumowałem je. "for (;;)" ma około 12 klawiszy-szerokości ruchów do tyłu i czwartej (między klawiszami home i klawiszami oraz między klawiszami home i klawiszem SHIFT) "while (TRUE)" ma około 14 klucz-szerokość ruchów do tyłu i czwarty.

Jednak jestem znacznie mniej podatny na błędy podczas wpisywania tego drugiego. Myślę mentalnie słowami na raz, więc szybciej piszę rzeczy takie jak "nIndex" niż akronimy takie jak "nIdx", ponieważ muszę mentalnie przeliterować literę zamiast mówić ją w moim umyśle i pozwolić moim palcom automatycznie wpisywać słowo (jak jazda na rowerze)

(mój TypingTest.com benchmark = 136 WPM)

 9
Author: Mark Rejhon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:14:08

Wszystkie dobre odpowiedzi-zachowanie powinno być dokładnie takie samo.

Jednak - przypuśćmy, że to coś zmieniło. Załóżmy, że jeden z nich wziął jeszcze 3 instrukcje na iterację.

Powinno cię to obchodzić?

Tylko wtedy, gdy to, co robisz wewnątrz pętli, jest prawie niczym, czyli prawie nigdy .

Chodzi mi o to, że jest mikro-optymalizacja i makro-optymalizacja. Mikro-optymalizacja jest jak "strzyżenie, aby schudnąć".

 6
Author: Mike Dunlavey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-10 00:36:09
for(;;Sleep(50))
{
    // Lots of code
}

Jest jaśniejszym niż:

while(true)
{
    // Lots of code
    Sleep(50);
}

Nie ma to zastosowania, jeśli nie używasz Sleep().

 6
Author: Armada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 05:12:21

Nie wyobrażam sobie, aby wartościowy kompilator generował inny kod. Nawet gdyby tak było, nie byłoby sposobu na określenie bez przetestowania konkretnego kompilatora, który byłby bardziej wydajny.

Jednak sugeruję, abyś wybrał for(;;) z następujących powodów:

  • Wiele używanych przeze mnie kompilatorów wygeneruje ostrzeżenie o wyrażeniu stałym dla while(true) z odpowiednimi ustawieniami poziomu Ostrzeżenia.

  • W twoim przykładzie makro TRUE może nie być zdefiniowany zgodnie z oczekiwaniami

  • Istnieje wiele możliwych wariantów nieskończonej pętli while, takich jak while(1), while(true), while(1==1) itd.; więc for(;;) prawdopodobnie spowoduje większą spójność.

 5
Author: Clifford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:34:37

Pętla "forever" jest popularna w systemach wbudowanych jako pętla tła. Niektórzy implementują go jako:

for (; ;)
{
 // Stuff done in background loop
}

I czasami jest zaimplementowany jako:

while (TRUE /* or use 1 */)
{
 // Stuff done in background loop
}

I jeszcze jedna implementacja to:

do
{
 // Stuff done in background loop
} while (1 /* or TRUE */);

Kompilator optymalizujący powinien wygenerować ten sam lub podobny kod Złożenia dla tych fragmentów. Jedna ważna uwaga: czas wykonania pętli nie jest dużym problemem, ponieważ pętle te trwają wiecznie, a więcej czasu spędza się w sekcji przetwarzania.

 4
Author: Thomas Matthews,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 22:14:06

Zakładam, że while (true) jest bardziej czytelne niż dla(;;) -- wygląda na to, że programista tęskni za czymś w pętli :)

I kogo to obchodzi który jest szybszy jeśli w ogóle

 2
Author: nik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-10 15:16:49

Najważniejszym powodem używania "for (;;) "jest strach przed używaniem" while(TRUE) " podczas programowania eksploracyjnego. Łatwiej jest kontrolować ilość powtórzeń za pomocą "for", a także łatwiej przekształcić pętlę " for " w nieskończoność.

Na przykład, jeśli konstruujesz funkcję rekurencyjną, możesz ograniczyć liczbę wywołań funkcji przed przekształceniem w pętlę nieskończoną.

    for(int i=0;i<1000;i++) recursiveFunction(oneParam);

Kiedy jestem pewien swojej funkcji, to zamieniam ją na nieskończoną loop:

    for(;;) recursiveFunction(oneParam);
 2
Author: Ignacio Cortorreal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-29 05:49:39