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
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())
{
}
^ br .
#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.
Hangisi daha hızlı, (bayrak==0) veya (...
.Döngü daha hızlı çalışır NET,' v...
'daha hızlı s, AYRI veya GRUP MyS...
Hangisi daha hızlıdır? SELECT SQL_CALC...
Python ile daha hızlı olan: x**.5 veya...