2012-04-11 133 views
6

可能重複:
C++ string::find complexity性能的std ::對比的strstr的std :: string ::找到

最近我發現,該功能std::string::find是一個量級慢比功能std::strstr - 在我的Linux環境中使用GCC 4.7。性能差異取決於字符串的長度和硬件架構。

但是,有一個簡單的原因有所不同:std::string::find基本上在一個循環中調用std::memcmp - 時間複雜度爲O(m * n)。相比之下,std::strstr針對硬件體系結構(例如,使用SSE指令)進行了高度優化,並使用更復雜的字符串匹配算法(顯然是Knuth-Morris-Pratt)。

我也很驚訝沒有在語言文檔(即草稿N3290和N1570)中找到這兩個函數的時間複雜性。我只找到了時間複雜度爲char_traits。但是這並沒有幫助,因爲在char_traits中沒有子字符串搜索的功能。

我認爲,std::strstrmemmem包含類似的優化幾乎相同的性能。直到最近,我還是假定std::string::find在內部使用memmem

的問題是:有沒有什麼好的理由,爲什麼std::string::find不使用std::memmem?這與其他實現有何不同?

問題不在於:這個函數的最佳實現是什麼?如果它比C慢,那麼爲C++辯論真的很困難。如果兩種實現都很慢,我就不會擔心了。這是真正傷害的性能差異。

+0

@FrerichRaabe:你說的對,這兩個問題有一些重疊。但是我的問題更具體,而另一篇文章沒有回答。 – nosid 2012-04-11 07:11:07

+0

@nosid:是的。尤其要特別注意dietmar kuhl在評論中關於平均情況對最壞情況和空間複雜度的額外解釋,爲什麼這很可能不被使用。如果從頭開始重用執行算法的'std :: memmem',那麼這些參數不會改變。 – KillianDS 2012-04-11 07:15:42

回答

2

首先,什麼是memmem?我無法在C++標準中找到它,也不能在Posix標準中找到它(它包含所有的標準C函數)。

其次,任何測量值將取決於實際數據。例如,使用 在很多情況下,KMP就會成爲一種悲觀主義;大概 使用std::string的成員函數的大多數情況; 設置必要表的時間往往會比直接算法的總時間多 。像O(m*n) 這樣的東西在字符串的典型長度很短時沒有多大意義。

+0

我推測,memmem是C的一部分,但顯然不是。 'memmem'是'strstr'什麼'memcmp'是'strcmp'。不過,我相信你知道這一點。不過,正如我已經提到過幾次。問題不在於KMP是不錯的選擇。問題是,爲什麼他們對'strstr'和'std :: string :: find'使用完全不同的算法。 – nosid 2012-04-11 08:46:37

+0

@nosid也許是因爲預期的使用模式不同?或者因爲不同的作者有不同的使用模式的特權?在我看到的大多數應用程序中,大多數字符串都很短,最長的字符串可能對應於一行。對於這樣的字符串,使用像KMP這樣的東西可能是一種悲觀。如果'memmem'的作者認爲典型的用例會涉及幾KB或更多的內存塊,那麼這絕對是值得的。 – 2012-04-11 09:01:45

+0

根據我的基準測試,截至25.06.2013:對於GCC,string :: find速度稍快(〜10%)(x86_64,-march = native,在AWS上運行) - 對於MSVC 2,速度較慢(x86,SSE2 ,在AMD臺式機上)。 (完全優化) – Etherealone 2013-06-25 01:00:59