1樓:
簡要答案:
因為你沒利用strstr的返回值,這個函式根本就沒被呼叫。而編譯器不敢優化你自己寫的函式。
具體過程:
我們來進行一下測試:
1. g++ 5.3.0, Linux x64
編譯選項:g++ -g -o test test.cpp
執行結果:
~ git:(master) ./test 01
~ git:(master) ./test01
~ git:(master) ./test10
~ git:(master) ./test01
~ git:(master) ./test01
~ git:(master) ./test10
~ git:(master) ./test01
~ git:(master) ./test10
總體來說,兩者速度差不多
反彙編看看:
objdump -dS test
test函式呼叫:
int start_t, end_t, i;
start_t = time(NULL);
4008bd: bf 00 00 00 00mov $0x0,%edi
4008c2: e8 89 fe ff ffcallq 400750
4008c7: 89 45 f8mov %eax,-0x8(%rbp)
for( i = 0; i < 200000000; i++)
4008ca: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
4008d1: 81 7d fc ff c1 eb 0b cmpl $0xbebc1ff,-0x4(%rbp)
4008d8: 7f 19jg 4008f3 //比較,>=200000000 則跳出迴圈test(src, des);
4008da: 48 8d 55 d0lea -0x30(%rbp),%rdx //可以看出,這裡對test的呼叫是通過暫存器傳值的,用了乙個call,需要壓棧
4008de: 48 8d 45 e0lea -0x20(%rbp),%rax
4008e2: 48 89 d6mov %rdx,%rsi
4008e5: 48 89 c7mov %rax,%rdi
4008e8: e8 69 ff ff ffcallq 400856 <_Z4testPKcS0_>
char src = "GCGCBGGAGTCAGAe";
char des = "CAGAG";
int start_t, end_t, i;
start_t = time(NULL);
for( i = 0; i < 200000000; i++)
4008ed: 83 45 fc 01addl $0x1,-0x4(%rbp)
4008f1: eb dejmp 4008d1 //進行下一輪迴圈test(src, desend_t = time(NULL);
4008f3: bf 00 00 00 00mov $0x0,%edi //結束迴圈
4008f8: e8 53 fe ff ffcallq 400750
而strstr:
start_t = time(NULL);
40091f: bf 00 00 00 00mov $0x0,%edi
400924: e8 27 fe ff ffcallq 400750
400929: 89 45 f8mov %eax,-0x8(%rbp)
for( i = 0; i < 200000000; i這裡根本就沒有strstr相關的呼叫,因為被優化掉了
40092c: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
400933: 81 7d fc ff c1 eb 0b cmpl $0xbebc1ff,-0x4(%rbp)
40093a: 7f 06jg 400942
40093c: 83 45 fc 01addl $0x1,-0x4(%rbp)
400940: eb f1jmp 400933 strstr(src, desend_t = time(NULL);
400942: bf 00 00 00 00mov $0x0,%edi
400947: e8 04 fe ff ffcallq 400750
40094c: 89 45 f4mov %eax,-0xc(%rbp)
總結:因為你的test函式基本都是暫存器操作,所以耗時也很少。而strstr根本就沒被呼叫,所以兩者速度差不多,
2. clang++ 3.7
編譯選項:
clang++ -g -o test test.cpp
執行結果:
~ git:(master) ./test02
~ git:(master) ./test02
~ git:(master) ./test02
有了明顯差距。
看一看反彙編:
objdump -dS test
start_t = time(NULL);
400a18: 48 89 45 c0mov %rax,-0x40(%rbp)
400a1c: e8 7f fd ff ffcallq 4007a0
400a21: 89 c1mov %eax,%ecx
400a23: 89 4d d4mov %ecx,-0x2c(%rbp)
for( i = 0; i < 200000000; i++)
400a26: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%rbp)
400a2d: 81 7d cc 00 c2 eb 0b cmpl $0xbebc200,-0x34(%rbp)
400a34: 0f 8d 1f 00 00 00 jge 400a59
400a3a: 48 8d 75 dalea -0x26(%rbp),%rsi
400a3e: 48 8d 7d e0lea -0x20(%rbp),%rdistrstr(src, des);
400a42: e8 59 00 00 00callq 400aa0 <_ZSt6strstrPcPKc>
// 不出所料,發生了呼叫
400a47: 48 89 45 b8mov %rax,-0x48(%rbpend_t = time(NULL);
cout<
為什麼 C 中使用虛函式時會影響效率?
C 中使用虛函式不會影響效率。你遇到的場景,都沒到需要考慮流水線 friendly 的程度,先把東西寫出來,別想沒用的。 maple 因為查詢虛函式表的時候會有效率損失,可以通過模板的CRTP技術實現靜態繫結,詳見 C CRTP Curiously Recurring Template Patter...
程式設計的函式和數學的函式為什麼都叫函式?
哲學嘉 本質是一樣的,電腦程式的函式概念基於數學上的函式,只不過加了一些操作在裡面,所以變得跟數學上的函式有點不一樣 計算機中的函式包含輸入 輸出 資料處理還有操作 比如輸出到螢幕 而數學上的函式只關注數。在數學上,輸入 資料處理 輸出,這三者缺少任何乙個都是沒有意義的,而在電腦程式裡,就算你輸入 ...
為什麼冪函式不叫底數函式
令狐帝主 冪函式叫底數函式完全沒問題,而且跟指數函式對應,底數函式 指數函式描述了自變數的位置。而對數函式,可以認為求自變數 真數 之對數的函式。 趙洪生 能找到這裡的人,說明都經歷了思考,我也是一樣的。可以心裡把它叫為底數函式,說出來的時候還是冪函式,自己明白的同時也能跟別人交流。話說另外的問題,...