7

重複の可能性:
C++ string::find complex

最近、Linux で GCC 4.7 を使用している私の環境ではstd::string::find、関数が関数よりも桁違いに遅いことに気付きました。std::strstrパフォーマンスの違いは、文字列の長さとハードウェア アーキテクチャによって異なります。

違いには単純な理由があるようです。std::string::find基本的std::memcmpにはループで呼び出します-時間の複雑さがありO(m * n)ます。対照的にstd::strstr、ハードウェア アーキテクチャ (SSE 命令など) 向けに高度に最適化されており、より洗練された文字列一致アルゴリズム (明らかに Knuth-Morris-Pratt) を使用しています。

また、これら 2 つの関数の時間の複雑さが言語ドキュメント (つまり、ドラフト N3290 と N1570) にないことにも驚きました。の時間の複雑さだけが見つかりましたchar_traits。しかし、 には部分文字列検索の機能がないため、これは役に立ちませんchar_traits

私は、ほぼ同じパフォーマンスで同様の最適化が含まれていることstd::strstrを期待しています。memmemそして最近まで、私はそれが内部的にstd::string::find使用されていると思っていました。memmem

質問は次のとおりです。正当な理由はありますか、なぜstd::string::find使用しないのstd::memmemですか? また、他の実装では異なりますか?

問題は、この関数の最適な実装は何かということではありません。C++ が C よりも遅い場合、C++ を支持するのは本当に難しいです。両方の実装が遅いかどうかは問題ではありません。本当に痛いのはパフォーマンスの違いです。

4

1 に答える 1

2

まず、なにmemmem?これは、C++ 標準にも Posix 標準 (すべての標準 C 関数を含む) でも見つかりません。

第二に、測定値は実際のデータに依存します。たとえば、KMP を使用すると、多くの場合悲観的になります。おそらくほとんどの場合、 のメンバー関数std::stringが使用されます。必要なテーブルを設定する時間は、単純なアルゴリズムの合計時間よりも多くなることがよくあります。文字列の典型的な長さが短い場合、そのようなO(m*n) ことはあまり意味がありません。

于 2012-04-11T08:09:14.153 に答える