int fact1(int limit)
{
for (i=1;i<limit;i++) fact *= i;
}
int fact2(int limit)
{
for (i=limit; i!=0; i--) fact *= i;
}
這個是當時上學老師出的一道題,我也覺得應該效率一樣,不知道各位有什麼不同看法
根據10樓兄弟的回答,我用objdump的反匯編結果如下:
00000000004004c2 <fact1>:
4004c2: 55 push %rbp
4004c3: 48 89 e5 mov %rsp,%rbp
4004c6: 89 7d ec mov %edi,-0x14(%rbp)
4004c9: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
4004d0: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
4004d7: c7 45 f8 01 00 00 00 movl $0x1,-0x8(%rbp)
4004de: eb 0e jmp 4004ee <fact1+0x2c>
4004e0: 8b 45 fc mov -0x4(%rbp),%eax
4004e3: 0f af 45 f8 imul -0x8(%rbp),%eax
4004e7: 89 45 fc mov %eax,-0x4(%rbp)
4004ea: 83 45 f8 01 addl $0x1,-0x8(%rbp)
4004ee: 8b 45 f8 mov -0x8(%rbp),%eax
4004f1: 3b 45 ec cmp -0x14(%rbp),%eax
4004f4: 7c ea jl 4004e0 <fact1+0x1e>
4004f6: 5d pop %rbp
4004f7: c3 retq
00000000004004f8 <fact2>:
4004f8: 55 push %rbp
4004f9: 48 89 e5 mov %rsp,%rbp
4004fc: 89 7d ec mov %edi,-0x14(%rbp)
4004ff: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
400506: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
40050d: 8b 45 ec mov -0x14(%rbp),%eax
400510: 89 45 f8 mov %eax,-0x8(%rbp)
400513: eb 0e jmp 400523 <fact2+0x2b>
400515: 8b 45 fc mov -0x4(%rbp),%eax
400518: 0f af 45 f8 imul -0x8(%rbp),%eax
40051c: 89 45 fc mov %eax,-0x4(%rbp)
40051f: 83 6d f8 01 subl $0x1,-0x8(%rbp)
400523: 83 7d f8 00 cmpl $0x0,-0x8(%rbp)
400527: 75 ec jne 400515 <fact2+0x1d>
400529: 8b 45 fc mov -0x4(%rbp),%eax
40052c: 5d pop %rbp
40052d: c3 retq
應該和你的覺過一樣,減法可以直接判斷,加法多了一個mov,但是我這邊怎麼這麼繁瑣,沒你的簡易
反匯編一下就知道區別了。
循環條件的判斷,一個是迭代量跟某個固定值的比較(cmp %eax, XXX),一個是迭代量是否為0的比較(test %eax, %eax)。
cmp和test的效率有區別嗎?
-O3之後,就會發現,循環體是4條指令跟3條指令的區別。
也就是說,可以直接利用減法的結果來進行判斷調整,加法則不行,還需要額外的比較。
.L4:
imull %eax, %edx
addl $1, %eax
cmpl %edi, %eax
jne .L4
.L14:
imull %eax, %edx
subl $1, %eax
jne .L14