2016-05-22 7 views
-4

元の質問はひどく受け取り、多くの下降音を得ました。だから私は、読むことをより簡単にし、それを見ている人にもっと助けになるように質問を修正すると思った。元の質問は、なぜ文字列を手動でループして '\ 0'文字を見つけるよりも、strlen()が20倍高速だったからです。私は、文字列の長さがnull終端文字 '\ 0'を見つけるまで本質的にループしていることを見つけるstrlen()のテクニックをどこでも読んでいたので、この質問はうまくいきました。これはC文字列の一般的な批判です。まあ、多くの人々が指摘するように、Cライブラリの一部である関数は、パフォーマンスを最大限にするためにスマートなプログラマーによって作成されます。ヌルで終了する文字をチェックするために手動でループするよりも、strlen()が約20倍速いのはなぜですか?

ilen2のおかげでビット演算子を使用して一度に8バイトの演算子を使う巧妙な方法にリンクしてくれたので、8〜15文字よりも大きな文字列ではstrlen )、文字列がかなり大きいときはstrlen()より何倍も速くなります。例えば、strange()は、文字列の長さに応じて線形に時間依存するように見えます。一方、カスタムの文字列の長さに関係なく(私は数百までテストした)ほとんど同じ時間量を要します。とにかく、私の結果は驚くべきことですが、私は最適化をオフにしてそれらを行いました、そして、彼らがどれほど有効であるか分かりません。このリンクのためにilen2とJohn Zwinckに感謝します。興味深いことに、John ZwinckはSIMDをstrlen()が高速にする可能性があると示唆しましたが、私はそれについて何も知らない。

+1

あなたの実装では、ループごとに2つの加算を使用します。私は1つの追加だけを使って方法を考えることができます。 – ilent2

+5

1つは最適化されたライブラリへのライブラリ呼び出しであり、もう1つは最適化されていないアルゴリズムの上に最適化されていないアセンブリの一部です。これは、「オーブンを使って、卵を冷蔵庫の横の袋に入れるよりも早く卵を作るのはなぜですか?」と尋ねるのと同じです。 – Yakk

+3

コンパイラはコンパイル時に文字列の長さを計算することができるということをコンパイラが認識できる可能性があるので、これは最適な例ではありません。より良い例は、最初にさまざまな長さの文字列をメモリ(ファイルまたは他の場所から)にロードし、次にそれらの長さを決定することです。 – ilent2

答えて

5

strlen()は非常にヒットした機能であり、非常に明るいいくつかの人が最適化するために何日も何ヶ月も費やしていることに賭けることができます。一度アルゴリズムが正しくなると、次のことは、一度に複数のバイトをチェックできますか?答えはもちろん、SIMD(SSE)や他のトリックを使ってできることです。あなたのプロセッサが一度に128ビットで動作できるなら、それは1クロックではなく16クロックです。

+0

私はilent2が与えたリンクに基づいて何かを書いています。これは一度に8バイトをチェックしていますので、これまでの4回のテストはstrlen()より速くて、とてもうれしいです。 SIMDを使用するのは面白いでしょう、私はそれを使用する方法の手がかりを持っていないでしょう。 – Zebrafish

関連する問題