問題描述
長版...
今天一位同事在看到我在 Perl 腳本中使用 while (1)
后斷言 for (;;)
更快.我認為它們應該是相同的,希望解釋器可以優化任何差異.我設置了一個腳本,該腳本將運行 1,000,000,000 次循環迭代和相同數量的 while 循環并記錄之間的時間.我找不到明顯的區別.我的同事說一位教授告訴他 while (1)
正在做一個比較 1 == 1
和 for (;;)
不是.我們用 100 倍的 C++ 迭代次數重復了相同的測試,差異可以忽略不計.然而,這是一個圖形示例,說明編譯代碼與腳本語言相比可以快多少.
A co-worker asserted today after seeing my use of while (1)
in a Perl script that for (;;)
is faster. I argued that they should be the same hoping that the interpreter would optimize out any differences. I set up a script that would run 1,000,000,000 for loop iterations and the same number of while loops and record the time between. I could find no appreciable difference. My co-worker said that a professor had told him that the while (1)
was doing a comparison 1 == 1
and the for (;;)
was not. We repeated the same test with the 100x the number of iterations with C++ and the difference was negligible. It was however a graphic example of how much faster compiled code can be vs. a scripting language.
簡短版本...
如果您需要擺脫無限循環,是否有任何理由更喜歡 while (1)
而不是 for (;;)
?
Is there any reason to prefer a while (1)
over a for (;;)
if you need an infinite loop to break out of?
注意:如果問題不清楚.這純粹是幾個朋友之間有趣的學術討論.我知道這不是一個所有程序員都應該為之苦惱的非常重要的概念.感謝所有出色的回答,我(以及我相信其他人)從這次討論中學到了一些東西.
Note: If it's not clear from the question. This was purely a fun academic discussion between a couple of friends. I am aware this is not a super important concept that all programmers should agonize over. Thanks for all the great answers I (and I'm sure others) have learned a few things from this discussion.
更新:上述同事權衡了以下回復.
Update: The aforementioned co-worker weighed in with a response below.
在這里引用以防它被掩埋.
Quoted here in case it gets buried.
它來自一個 AMD 匯編程序員.他說 C 程序員(人們)沒有意識到他們的代碼效率低下.他說不過今天,gcc 編譯器非常好,把像他這樣的人趕出去的業務.例如,他說,并告訴我 while 1
與for(;;)
.我現在出于習慣使用它,但是 gcc 尤其是解釋器這兩天將執行相同的操作(處理器跳轉),因為它們已經過優化.
It came from an AMD assembly programmer. He stated that C programmers (the poeple) don't realize that their code has inefficiencies. He said today though, gcc compilers are very good, and put people like him out of business. He said for example, and told me about the
while 1
vsfor(;;)
. I use it now out of habit but gcc and especially interpreters will do the same operation (a processor jump) for both these days, since they are optimized.
推薦答案
在 perl 中,它們產生相同的操作碼:
In perl, they result in the same opcodes:
$ perl -MO=Concise -e 'for(;;) { print "foo
" }'
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
"] s ->7
8 <0> unstack v ->4
-e syntax OK
$ perl -MO=Concise -e 'while(1) { print "foo
" }'
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
"] s ->7
8 <0> unstack v ->4
-e syntax OK
同樣在 GCC 中:
#include <stdio.h>
void t_while() {
while(1)
printf("foo
");
}
void t_for() {
for(;;)
printf("foo
");
}
.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
所以我想答案是,它們在許多編譯器中都是一樣的.當然,對于其他一些編譯器來說,情況可能不一定如此,但循環內的代碼很可能比循環本身貴幾千倍,所以誰在乎?
So I guess the answer is, they're the same in many compilers. Of course, for some other compilers this may not necessarily be the case, but chances are the code inside of the loop is going to be a few thousand times more expensive than the loop itself anyway, so who cares?
這篇關于而 (1) Vs.for (;;) 有速度差異嗎?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!