其他人已經提供了一些優秀的commen包括對生成的彙編代碼的分析。我強烈建議你仔細閱讀。正如他們指出的,這種問題如果沒有量化就不能真正回答,所以讓我們一起玩吧。
首先,我們將需要一個程序。我們的計劃是這樣的:我們將生成長度爲2的字符串,並依次嘗試所有函數。我們運行一次來初始化緩存,然後分別使用我們可用的最高分辨率進行4096次迭代。一旦完成,我們將計算一些基本的統計數據:min,max和簡單移動平均值並轉儲它。然後我們可以做一些基本的分析。
除了你已經顯示的兩種算法之外,我將展示第三個選項,它根本不涉及使用計數器,而是依賴於減法,我將通過投擲來混合東西在std::strlen
,只是爲了看看會發生什麼。這將是一個有趣的回合。
通過我們的小程序已經寫入電視的魔力,所以我們用gcc -std=c++11 -O3 speed.c
編譯它,我們得到起動產生一些數據。我做了兩個單獨的圖,一個是字符串,大小從32到8192字節,另一個是字符串,長度從16384到1048576字節。在下面的圖表中,Y軸是在納秒內消耗的時間,X軸以字節爲單位顯示字符串的長度。
事不宜遲,讓我們來看看從32 「小」 的字符串表現爲8192個字節:
現在這是有趣的。 std::strlen
的功能不僅僅是性能優於所有的功能,而且它的性能也更加穩定。
會,形勢的變化,從16384如果我們看一下大串一路1048576個字節長?
的排序。差異變得更加明顯。由於我們的自定義編寫的功能唾手可得,std::strlen
繼續執行令人欽佩。
一個有趣的現象,使的是,你不一定能轉化的C++的指令數(甚至,彙編指令數)的性能,因爲其功能包括機構較少的指令有時需要更長的時間來執行。
更有意思的是 - 和重要觀察是要注意str::strlen
功能如何執行。
那麼,這一切是什麼讓我們?
第一個結論:不要重新發明輪子。使用可用的標準功能。它們不僅是已經寫好的,而且它們的優化程度非常高,幾乎肯定會勝過你可以編寫的任何東西,除非你是Agner Fog。第二個結論:除非你有一個硬數據從一個代碼或函數的特定部分是你的應用程序中的熱點,不要打擾優化代碼。程序員通過查看高級功能在檢測熱點方面非常不好。
第三個結論:寧可爲了提高代碼的性能算法最優化。讓你的思想工作,並讓編譯器隨機播放。
您原來的問題是:「爲什麼函數slen2
慢於slen1
?」我可以說,沒有更多的信息就不容易回答,即使如此,它可能會比你所關心的要長得多,涉及更多。相反,我會說這是:
誰在乎,爲什麼?你爲什麼還要打擾呢?使用std::strlen
- 這比任何你可以設置的更好 - 然後繼續解決更重要的問題 - 因爲我確信這個不是是你應用程序中最大的問題。
爲什麼使用double而不是unsigned long?另外,您應該嘗試編譯而不進行優化並查看結果。哦,你應該運行約二十次,並計算平均持續時間。 – 2011-05-30 20:01:09
分支預測失敗?不必要的數據副本?嘗試查看生成的程序集。此外,嘗試開啓優化,它可能會解決問題。 – dmckee 2011-05-30 20:02:25
你使用什麼樣的編譯器?我用gcc 4.4.5運行它,它們幾乎在同一時間,大約2s。隨着我設置爲110021100,他們都使用大約19秒。 – 2011-05-30 20:03:10