strstr函式的效率為什麼那麼高?

時間 2021-06-23 22:44:16

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...

程式設計的函式和數學的函式為什麼都叫函式?

哲學嘉 本質是一樣的,電腦程式的函式概念基於數學上的函式,只不過加了一些操作在裡面,所以變得跟數學上的函式有點不一樣 計算機中的函式包含輸入 輸出 資料處理還有操作 比如輸出到螢幕 而數學上的函式只關注數。在數學上,輸入 資料處理 輸出,這三者缺少任何乙個都是沒有意義的,而在電腦程式裡,就算你輸入 ...

為什麼冪函式不叫底數函式

令狐帝主 冪函式叫底數函式完全沒問題,而且跟指數函式對應,底數函式 指數函式描述了自變數的位置。而對數函式,可以認為求自變數 真數 之對數的函式。 趙洪生 能找到這裡的人,說明都經歷了思考,我也是一樣的。可以心裡把它叫為底數函式,說出來的時候還是冪函式,自己明白的同時也能跟別人交流。話說另外的問題,...