私はあなたを保証することができます、機能strcmp
は絶対にボトルネックではありません。通常、strcmpは十分に最適化されており、アーキテクチャに応じて4/8バイトより長い文字列に対して32ビットまたは64ビットの比較を実行できます。newlibとGNUlibcの両方がこれを行います。ただし、両方の文字列の各バイトを20回見たとしても、ここで行ったアルゴリズムとデータ構造の選択ほど重要ではありません。
実際のボトルネックは、O(N)検索アルゴリズムです。ファイルでの単一のO(N log N)パスを使用して、O(log N)ルックアップを実行するための適切なデータ構造(通常のBST、トライ、または単純なソートされた配列)を使用できます。
ここで私と一緒に耐えてください-多くの数学が続きます。しかし、これは、アルゴリズムとデータ構造の選択が文字列比較の方法よりもはるかに重要である理由を説明する良い機会だと思います。スティーブはこれに触れていますが、もう少し詳しく説明したいと思います。
N = 1e6の場合、log(1e6、2)= 19.9であるため、理想的なデータ構造で20回の比較に切り上げます。
現在、O(N)または1e6操作の最悪の場合の検索を行っています。
つまり、O(log N)挿入時間で赤黒木を構築し、N個のアイテムを挿入するとします。これは、ツリーを構築するためのO(N log N)時間です。つまり、ツリーを構築するために必要な1e6x20または20e6の操作です。
現在のアプローチでは、データ構造の構築はO(N)または1e6操作ですが、最悪の場合の検索時間もO(N)です。したがって、ファイルを読み取って20回の検索操作を実行するまでに、理論上最悪の場合の21,000,000回の操作になります。比較すると、赤黒木と20回の検索での最悪のケースは、20,000,400回の操作、つまり、ソートされていない配列でのO(N)検索よりも999,600回の操作の方が優れています。つまり、20回の検索で、より洗練されたデータ構造が実際に成果を上げる最初のポイントになります。しかし、1000回の検索で何が起こるかを見てください。
ソートされていない配列=初期化+1000x検索時間=O(N)+ 1000 * O(N)= 1,000,000 + 2,000,000,000=2,001,000,000回の操作。
赤黒=初期化+1000x検索時間=O(N log N)+ 1000 * O(log N)= 20,000,000 + 20,000=20,020,000操作。
2,001,000,000 / 20,020,000〜= O(N)検索の100倍の操作。
1e6検索では、(1e6 + 1e6 * 1e6)/(20e6 + 1e6 * 20)=25,000倍の操作になります。
コンピュータが1分でlogN検索を実行するのに必要な40e6の「操作」を処理できると仮定します。現在のアルゴリズムで同じ作業を行うには、25,000分、つまり17日かかります。または、別の見方をすれば、O(log N)アルゴリズムが1,000,000を実行できる時間内に、O(N)検索アルゴリズムは39回の検索しか処理できないということです。そして、検索を増やすほど、醜くなります。
データ構造とアルゴリズムのより良い選択については、Steveからの回答を参照してください。私の唯一の追加の注意はqsort()
、スティーブによって提案されたO(N * N)の最悪の場合の複雑さを持っているかもしれないということです。これは、ヒープソートまたはさまざまなツリーのようなもので得られるO(N log N)よりもはるかに悪いです。構造。