Hangisi daha hızlı: while(1) veya(2)? | Netgez.com
SORU
20 Temmuz 2014, Pazar


Hangisi daha hızlı: while(1) veya(2)?

Bu röportaj bir soru üst düzey bir yöneticisi tarafından soruldu.

Daha hızlı olan?

while(1) {
    // Some code
}

ya

while(2) {
    //Some code
}

while içindeki ifade sonunda true false değerlendirmek gerektiği gibi, her ikisi de aynı yürütme hızı var dedim. Bu durumda, her ikisi de 21* *Değerlendirme ve while durum içinde ekstra koşullu talimatları vardır. Böylece, hem yürütme, aynı hız ve Süre (1) tercih ederim.

Ama görüşmeci güvenle söyledi: "Temel kontrol edin. while(1) while(2)."daha hızlı. (Güvenimi test ediyordu

Bu doÄŸru mu?

Ayrıca bakınız: Is "for(;;)" faster than "while (TRUE)"? If not, why do people use it?

CEVAP
20 Temmuz 2014, Pazar


Her iki döngüler sonsuz, ancak daha fazla talimatları yineleme başına/kaynaklarını alır görüyoruz.

Gcc kullanarak, optimizasyon değişik seviyelerde montaj için iki aşağıdaki programlardan derlenmiş:

int main(void)
{
    while(1)
    {
    }

    return 0;
}


int main(void)
{
    while(2)
    {
    }

    return 0;
}

Herhangi bir iyileştirme (-O0) bileoluşturulan Kurul, her iki program için aynı.Bu nedenle, iki döngüler arasında hız farkı yok.

Başvuru için, burada oluşturulan derleme (iyileştirme bayrağı gcc main.c -S -masm=intel kullanarak):

-O0: ile

    .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"

-O1: ile

    .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"

-O2 -O3 (aynı çıkış):

    .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"

Aslında, Meclis döngü optimizasyonu her seviye için aynıdır için üretilen:

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

Önemli bit olmak:

.L2:
    jmp .L2

Montaj çok iyi okuyamıyorum, ama bu tabii ki koşulsuz bir döngü. jmp talimat koşulsuz olarak geri program tabii ki gerçek karşı, ve hemen bir değer programın bir şekilde sona kadar tekrar yapar bile karşılaştırmadan .L2 etiket sıfırlar. Bu doğrudan C/C koduna karşılık gelir:

L2:
    goto L2;

Düzenleme:

İlginçtir ki, olsa bileherhangi bir iyileştirmeaşağıdaki döngüler hepsi aynı çıktı (jmp koşulsuz) Meclis üretilen:

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)
{
}

Ve hatta benim hayretle için:

#include<math.h>

while(sqrt(7))
{
}

while(hypot(3,4))
{
}

Şey kullanıcı tanımlı fonksiyonlar ile biraz daha ilginç olsun

int x(void)
{
    return 1;
}

while(x())
{
}

#include<math.h>

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

while(x())
{
}

-O0, bu iki örnek aslında x Ara ve her yineleme için bir karşılaştırma yapmak.

İlk örnek (1 dönen):

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

İkinci örnek (sqrt(7) döndürme):

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

Ancak, -O1 ve yukarıda, her ikisi de bir önceki örnek olarak aynı Meclisi (önceki etiket jmp koşulsuz geri) üretmek.

TL;DR

Farklı döngüler derleme derlenmiş, derleyici sabit değerleri değerlendirir ve herhangi bir fiili karşılaştırma gerçekleştirme rahatsız etmiyor, iki döngüler aynıdır.

Eğer bu davranış, tüm Derleyiciler/platformlarda tutarlı olduğunu kanıtlamak değilse bile, derleyici kanıtlıyorolabilirbu döngüler aynı olması için optimize, ve bu nedenlegerekir. Derlenmiş bir dil kullanarak ana avantajlarından biri, bu tür bir şey programcı endişe dışında olması gerekiyordu olmasıdır.

Bunu PaylaÅŸ:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VÄ°DEO

Rastgele Yazarlar

  • CaliforniaMetin

    CaliforniaMe

    3 ÅžUBAT 2013
  • How It Should Have Ended

    How It Shoul

    5 Mart 2007
  • SunsetTrance

    SunsetTrance

    20 EYLÃœL 2008