2012-01-21 8 views
14

最近、数十万の値を含む配列に問題がありました。唯一必要なのは、値がすでに存在するかどうかをチェックすることでした。 私の場合、これはWebサーバーログからのIPです。 だから、基本的のようなもの:検索時間が劇的に増加し、検索の10Kは約17秒ほどかかりましたがPHPでは配列とは別のデータ構造がありますが、私はさまざまなインデックス手法を利用できますか?

in_array(ip2long(ip),$myarray)は、ジョブ

をしました。

この場合、重複しているかどうかは気にしませんでした。存在を確認する必要がありました。だから私はこのようなインデックスにIPアドレスを格納することができ:

isset($myarray[ip2long($ip)]) 

とブーム、ルックアップ時間は10Kルックアップのために0.8秒の静的な時間まで17秒(およびそれ以上)から行ってきました。配列の値として、私はちょうどint 1を使用しました。

おそらく配列インデックスは、log(n)検索時間とハッシュマップのインデックスを持つべきb-treeに基づいていると思います。

私の場合、インデックスはうまくいきましたが、値インデックスとしてハッシュマップを使用することができるデータ構造があります。複数の値があるかもしれません(重複があまりない範囲/検索リクエストを効率的に使用することはできません。ツリー構造の主な利点です)。

答えて

7

リンクリスト、スタック、ヒープ、キューなど

含むPHPにバンドルSPL libraryで単純な配列、超えた代替のデータ構造の全体の範囲は、私はあなたのロジック全体の多くを作ることが疑われる、しかし、があります配列をflippedにするとより効率的です。値を検索するのではなく、キーを検索することができます(array_key_exists()関数を使用)。配列インデックスは、btreeではなくハッシュであり、キーを介して非常に高速な直接アクセスを行います。

しかし、配列の中で10kのエントリを扱っている場合は、独自のインデックスを定義できるデータベースを利用するほうがよいでしょう。

+0

ときどき良い解決策があなたの目の前にあり、複雑すぎると思うことがあります。 - うまくやった。 – Smamatti

+0

彼は私が理解しているところからそれをひっくり返した。 –

+0

issetは構造体であり、array_key_exists()は関数なので、isset($ a [$ key])の使用はarray_key_exists($ key、$ a)よりもはるかに高速です! – BurninLeo

1

配列には順序があり、ツリーをたどる必要はなく、シーケンシャルなリスト構造を使用する必要もないため、特定の要素にアクセスするのが簡単です。

もちろん、配列内のすべての要素ではなく一意の要素のみをチェックするので、ここでの設定はもちろん高速です。

ツリーは、ソートされた構造の例では問題ありません。範囲でソートされたIPを持つツリーを実装すると、このIPが存在するかどうかをより速く判断できます。 PHPがそのようなカスタマイズされたツリー構造を提供するかどうかはわかりません。私はあなた自身でこれを実装する必要があると思いますが、これには約30分かかります。

このようなツリー構造のサンプルコードはウェブ上にあります。

2

また、chdb(定数ハッシュデータベース)拡張機能もあります。これはこれに最適です。すでに答えとして

1

は、あなたはSPL http://www.php.net/spl

が提供するブランドの新しいクラスを使用することができますが、どうやら彼らは早く人々が考えるようではありません。おそらくそれらは私たちが期待するように実装されていません。それは例えば、実際の配列ではありません、splfixedarrayというのが私の意見ですが、ハッシュテーブルは、古典的なPHPの配列として

しかし、また、あなたには、いくつかの代替ソリューション

最初のデータベースにあなたの結果を保存することができますがあります。 DBのインデックスは、より良い

あなたは「あなたはドンので、私は、一時ファイルを示唆http://www.php.net/sqlite3、店舗一時データベース内の結果(ファイルまたはメモリ内)

を使用することができますPHPのデータ構造よりも、最適化することができるので、クエリが高速でありますメモリにすべてをロードする必要があります。さらに、各行を個別に追加することもできます(http://www.php.net/fgetsなど)

HTH!

関連する問題