1

マシンで生成されたログをperlからphpに解析するためにいくつかのスクリプトを書き直しているところです。ファイルの範囲は20mb〜400mbです。この問題が発生して、file()またはfopen()+ fgets()コンボを使用するかどうかを決定しています。パフォーマンスを向上させるためにファイルを介して。

これが基本的な実行方法です。ファイルを開く前にファイルサイズを確認します。ファイルが100mbより大きい場合(非常にまれなケースですが、時々発生します)、ぶつかっただけなのでfopen+fgetsルートに移動します。スクリプトのメモリ制限は384mbで、100mbを超えるファイルは致命的なエラーを引き起こす可能性があります。それ以外の場合は、file()を使用します。

両方の方法で、ファイルを最初から最後まで1行ずつ調べています。

ここに質問があります、小さなファイルを処理するためにコードのfile()部分を保持することは価値がありますか?file()(私はSKIP_EMPTY_LINEオプションも使用します)がphpでどのように機能するのかわかりませんが、ファイルを直接メモリにマップしますか、それともファイルを通過するときに行ごとにメモリに押し込みますか?私はそれにいくつかのベンチマークを実行しました、パフォーマンスはかなり近く、平均差は40mbファイルで約0.1秒であり、file()は約80%の時間(同じファイルセットでの200回のテストのうち)よりもfopen+fgetsよりも有利です。

ファイル部分を削除すると、システムから確実にメモリを節約できます。同じスクリプトの3つのインスタンスを同時に実行していることを考えると、データベースなどをホストしている12Gシステムで1G相当のメモリを節約できます。くだらない。ただし、スクリプトのパフォーマンスも低下させたくありません。これらのログは1日あたり10k程度入ってくるため、実際には0.1秒の差が加算されます。

どんな提案でも助けになるでしょうそしてTIA!

4

1 に答える 1

2

のような1つのメカニズムに固執することをお勧めしforeach(new \SplFileObject('file.log') as $line)ます。入力ファイルを分割し、CPUコアごとに2〜3倍の並列処理を行います。ボーナス:同じシステム上のデータベースよりも優先度が低くなります。PHPでは、これはスクリプトのN個のコピーを一度に生成することを意味します。各コピーには独自のファイルリストまたはディレクトリがあります。書き換えについて話しているので、IOパフォーマンスが問題になるため、ここでは、Java 7 NIO、nodejs非同期IO、C#TPLなど、より多くの機能を備えた他のプラットフォームを検討してください。

于 2012-05-05T03:28:56.983 に答える