2017-07-06 4 views
0

私はPHPで作成した検索を最適化する問題を抱えています。この検索は一度の使用であり、柔軟性はそれほど重要ではありません。複数の文書間で文の検索を最適化する

ように私は、文章の配列を持っている:配列を約1kの文章が含まれてい

$arr = [ 
    'potato', 
    'hi my name is Ivan' 
    .. 
]; 

私は200 GBのファイルを持つハードディスクを持っています。

すべてのファイルを検索し、これらの文のいずれかがファイル内にあるかどうかを確認する必要があります。その場合は、パス、チェックサムなどを特定の形式で出力する必要があります。

非効率的なようである、このような何かをやったときに私が直面しています問題は、検索時間です:

$objections = []; 
foreach ($files as $file) { 

    if (!in_array($file->getExtension(), $allowedExt)) 
     continue; 

    $txt = file_get_contents($file); 

    foreach ($words as $word) { 
     if (stripos($txt, $word) !== false || 
      stripos($file->getFilename(), $word) !== false 
      ) { 
      $file->c_md5 = getCMD5($file); 
      $objections[] = $file; 
     } 
    } 
} 

検索、それが自己+年齢1hのを取っている、と私は最新のi7のと新しいMacBookの午前。 PHPメモリなどを最大限に活用。

単語の配列にどの単語がマッチするかは関係ありません。そのため、ファイルループ内の単語をループする代わりに、検索を行うもっと巧妙な方法があるのだろうかと思いました。 ORを使った非常に長いREGEX文字列が高速になりますか?

また、いくつかの第3の方法がありますが、これはかなり高速です。

+0

私はドン」大きな正規表現が速くなるかどうかを知ることはできますが、あなたはそれを試してベンチマークしてみてください。その量のデータでは、おそらく非常に遅くなるでしょう。 –

答えて

0

確かに答えは正規表現です。おそらく、三つの段階に分割する必要があります

  1. がループ内で実行することが一つの大きな正規表現または正規表現のリストに文のリストに変換します。空白を空白に変換して\sとし、貪欲な検索を/regex/Uにすることができます。

  2. ファイルを反復処理し、改行を削除してスペースで置き換えます。文が複数の行にまたがっている場合に備えて。

  3. preg_matchを使用して、文章がファイルに含まれているかどうかを調べます。複数の正規表現を使用する場合は、ループ内で実行できます。

+1

私はあなたが正規表現に行くと、あなたは1つの大きな正規表現を持っている必要があります、そうでなければ、基本的にちょうど元のコードが何をやってゆっくりと実装されていると思う。正規表現は単純な文字列の比較には効率的ではありません。 (ただし、すべてのファイルのすべての文をループする必要がない場合は、より効率的になります)。 –

+0

@ MagnusEriksson私は同意する、1つの大きな正規表現が良いはずです。 –

+0

私は正規表現とベンチマークでテストします –

0

正規表現を使用すると、ほとんどまたはまったく節約できます。

ヒットしたときにループから脱出することができます。残りの検索を救う

Foreach{ 
    If(hit){ 
     Break; 
    } 
} 

。したがって、2回目の繰り返しを実行すると、そのドキュメントの998回の繰り返しを繰り返す必要はなくなります。

あなたが常に持っている問題は、ドキュメントのオープンです。間違いなく、パフォーマンスのほとんどが失われます。

これが複数回実行する必要がある操作の場合、すべてのファイルをフルテキスト検索ElasticSearch用に設計されたデータベースにインデックスすることを検討する価値があります。データベース内では、次の操作が何であっても、物理ファイルへの参照を保持することができます。 これらのファイルの初期読み込みとインデックス作成には、多大なリソースと時間がかかります。しかし、一度検索が完了したら、は本当にです。

+0

ああ、私はこれを追加するのを忘れていましたが、まあまあまあですが、ある程度の時間を節約する必要があります –

+0

私は真剣に述べたElasticSearchのようなデータベースを実装します。あなたはすでにすべてのファイルの内容を読み込んでいます。それをintibaデータベースに投げ込むのは簡単ではないので、検索には2つの機能が必要です。 ElasticSearchのドキュメントは素晴らしいです。 – Doug

+0

MySQLでのフルテキスト検索でさえ早くなるかもしれません。 –

0

あなたはtest.phpをファイルを作成exec

を使用して、このコード勿論

<?php 
    exec('grep '.escapeshellarg('end').' '."./test.php",$result);    
    print_r($result); 
    /* serach for some sentences 
    * keep seraching 
    * end of comment */ 
    ?> 

あなたが最初にその性能をテストし、あなたのニーズに合わせてカスタマイズする必要がありますを試すことができます

関連する問題