我們日常寫代碼時,經常自己去做一些優化,其實絕大多數情況都是沒必要的,因為編譯器比你想的聰明太多!
下面這個例子就是明證,
這個是一個求竭誠的遞歸寫法,很多老手都會告訴你這樣寫性能低,應該用循環。
int rfact(int x)
{
int rval;
if(x<=1)
return 1;
rval=rfact(x-1);
return rval*x;
}
我想大家一般都不會有什麼異議,那麼來看看生成的代碼是什麼樣子吧!
編譯方法 gcc –O2 –S rfact.c
我只貼上關鍵的匯編代碼,看看是不是毀三觀!
_rfact:
movl 4(%esp), %edx
movl $1, %eax
cmpl $1, %edx
jg L3
jmp L2
.p2align 4,,7
L9:
movl %ecx, %edx
L3:
leal -1(%edx), %ecx
imull %edx, %eax
cmpl $1, %ecx
jne L9
L2:
rep ret
看到了吧,沒有遞歸,沒有遞歸,沒有遞歸! 編譯器幫你轉換成循環了。 當然編譯不能把所有的遞歸都轉換成循環,但是可以看出大多數的優化真心沒必要,只會帶來錯誤, 比如使用右移來代替除法之類的,這些真心out了!
再給你看一個編譯器優化的例子,比你想的聰明多了。
int choice3(int x)
{
return 15*x;
}
你覺得這裡編譯器會用乘法?那你錯了!你錯了!你錯了!
_choice3:
movl 4(%esp), %edx
movl %edx, %eax
sall $4, %eax
subl %edx, %eax
ret
看到了麼?乘以16-1,聰明吧。