Re: [問題] 面試遇到的程式問題,現在還想不出來(MTK)
我用 VS2005 試了一下, 程式碼分別用:
void test()
{
for(i = 100; i >= 0; i--)
s = s + i;
}
void test2()
{
for(i = 100; --i; )
s += i;
}
// 這樣出來會是 4950, 不過意思到了就好
未開最佳化:
test:
for(i = 100; i >= 0; i--)
004130BE mov dword ptr [_i (417184h)],64h
004130C8 jmp test+37h (4130D7h)
004130CA mov eax,dword ptr [_i (417184h)]
004130CF sub eax,1
004130D2 mov dword ptr [_i (417184h)],eax
004130D7 cmp dword ptr [_i (417184h)],0
004130DE jl test+52h (4130F2h)
s = s + i;
004130E0 mov eax,dword ptr [_s (417188h)]
004130E5 add eax,dword ptr [_i (417184h)]
004130EB mov dword ptr [_s (417188h)],eax
004130F0 jmp test+2Ah (4130CAh)
test2:
for(i = 100; --i; )
0041340E mov dword ptr [_i (417184h)],64h
00413418 mov eax,dword ptr [_i (417184h)]
0041341D sub eax,1
00413420 mov dword ptr [_i (417184h)],eax
00413425 je test2+49h (413439h)
s += i;
00413427 mov eax,dword ptr [_s (417188h)]
0041342C add eax,dword ptr [_i (417184h)]
00413432 mov dword ptr [_s (417188h)],eax
00413437 jmp test2+28h (413418h)
這邊因為 for 少一個式子, 所以 test() 會簡短一些
i-- 和 --i, 我記得在 i 是基本型別的時候沒太大差別, 在 C++ 是物件的時候比較有差
開最佳化 (/O2):
test:
for(i = 100; i >= 0; i--)
00401020 mov ecx,dword ptr [s (403374h)]
00401026 mov eax,64h
0040102B jmp test+10h (401030h)
0040102D lea ecx,[ecx]
s = s + i;
00401030 add ecx,eax
00401032 sub eax,1
00401035 jns test+10h (401030h)
00401037 mov dword ptr [i (403370h)],eax
0040103C mov dword ptr [s (403374h)],ecx
test2:
for(i = 100; --i; )
00401050 mov ecx,dword ptr [s (403374h)]
00401056 mov eax,63h
0040105B jmp test2+10h (401060h)
0040105D lea ecx,[ecx]
s += i;
00401060 add ecx,eax
00401062 sub eax,1
00401065 jne test2+10h (401060h)
00401067 mov dword ptr [i (403370h)],eax
0040106C mov dword ptr [s (403374h)],ecx
時間一樣, 所以對於簡單內建型別的東西, 編譯器就可以處理大部份的最佳化
當然用一些更激進的寫法會更快, 不過可能就會犧牲易讀性
工作時間應該用來改進一些 compiler 沒辦法做的地方比較適合~
新增 gcc 的部分, 第一次反組譯 gcc 的執行檔, 應該有混一些其他的東西進去
(gcc -O2 直接把函式 inline 了)
有開最佳化 (-O2):
test:
:00401050 55 push ebp
:00401051 8B0D10304000 mov ecx, dword[00403010]
:00401057 BA64000000 mov edx, 00000064
:0040105C 891514304000 mov dword[00403014], edx
:00401062 89E5 mov ebp, esp
:00401064 B864000000 mov eax, 00000064
:00401069 8DB42600000000 lea esi, dword[esi+00000000]
---------
:00401070 8D1401 lea edx, dword[ecx+eax]
:00401073 48 dec eax
:00401074 89D1 mov ecx, edx
:00401076 79F8 jns 00401070
:00401078 5D pop ebp
:00401079 B8FFFFFFFF mov eax, FFFFFFFF
:0040107E A314304000 mov dword[00403014], eax
:00401083 891510304000 mov dword[00403010], edx
:00401089 C3 ret
test2:
:00401050 55 push ebp
:00401051 8B0D10304000 mov ecx, dword[00403010]
:00401057 BA63000000 mov edx, 00000063
:0040105C 891514304000 mov dword[00403014], edx
:00401062 89E5 mov ebp, esp
:00401064 B863000000 mov eax, 00000063
:00401069 8DB42600000000 lea esi, dword[esi+00000000]
---------
:00401070 8D1401 lea edx, dword[ecx+eax]
:00401073 48 dec eax
:00401074 89D1 mov ecx, edx
:00401076 75F8 jne 00401070
:00401078 5D pop ebp
:00401079 31C0 xor eax, eax
:0040107B A314304000 mov dword[00403014], eax
:00401080 891510304000 mov dword[00403010], edx
:00401086 C3 ret
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.50.147
推
01/02 21:08, , 1F
01/02 21:08, 1F
→
01/02 21:09, , 2F
01/02 21:09, 2F
→
01/02 21:40, , 3F
01/02 21:40, 3F
→
01/02 21:41, , 4F
01/02 21:41, 4F
※ 編輯: danielguo 來自: 220.135.50.147 (01/02 21:53)
討論串 (同標題文章)
完整討論串 (本文為第 4 之 12 篇):