5

タイマーに逆らうと、徐々に遅くなるスクリプトがあります。行を読み取り、それをチェックしてデータベースに追加し、次の行に進むだけなので、非常に簡単です。

徐々に悪化している出力は次のとおりです。

Record: #1,001 Memory: 1,355,360kb taking 1.84s
Record: #1,001 Memory: 1,355,360kb taking 1.84s
Record: #2,002 Memory: 1,355,192kb taking 2.12s
Record: #3,003 Memory: 1,355,192kb taking 2.39s
Record: #4,004 Memory: 1,355,192kb taking 2.65s
Record: #5,005 Memory: 1,355,200kb taking 2.94s
Record: #6,006 Memory: 1,355,376kb taking 3.28s
Record: #7,007 Memory: 1,355,176kb taking 3.56s
Record: #8,008 Memory: 1,355,408kb taking 3.81s
Record: #9,009 Memory: 1,355,464kb taking 4.07s
Record: #10,010 Memory: 1,355,392kb taking 4.32s
Record: #11,011 Memory: 1,355,352kb taking 4.63s
Record: #12,012 Memory: 1,355,376kb taking 4.90s
Record: #13,013 Memory: 1,355,200kb taking 5.14s
Record: #14,014 Memory: 1,355,184kb taking 5.43s
Record: #15,015 Memory: 1,355,344kb taking 5.72s

残念ながら、このファイルは約 20 GB 程度なので、この速度ですべてが読み込まれる頃にはおそらく死んでいるでしょう。コードは(主に)以下にありますが、 fgets() と関係があると思われますが、何がわからないのですか。

    $handle = fopen ($import_file, 'r');

    while ($line = fgets ($handle))
    {
        $data = json_decode ($line);

        save_record ($data, $line);
    }

前もって感謝します!

編集:

「save_record ($data, $line);」のコメントアウト 何もしないようです。

4

4 に答える 4

1

これらの大きなファイルを読み取るには、システムコマンドを使用する方がよい場合があります。私は似たようなものに出くわしました、そしてここに私が使ったちょっとしたトリックがあります:

$lines = exec("wc -l $filename");
for($i=1; $i <= $lines; $i++) {
   $line = exec('sed \''.$i.'!d\' '.$filename);

   // do what you want with the record here
}

信頼できないファイルではこれをお勧めしませんが、システムを使用して一度に1つのレコードをプルするため、高速に実行されます。お役に立てれば。

于 2010-08-17T23:24:39.420 に答える
0

http://php.net/manual/en/function.fgets.php

Leigh Purdieのコメントによると、が付いた大きなファイルにはパフォーマンスの問題がありますfgets。JSONオブジェクトが彼のテスト行よりも大きい場合は、制限がはるかに速くなる可能性があります

http://php.net/manual/en/function.stream-get-line.phpを使用して、長さの制限を指定します

于 2010-08-15T10:34:39.093 に答える
0

96G テキスト ファイルをより迅速に処理する方法を見つけようとしているときに、この質問を見つけました。私が最初に書いたスクリプトは、0.1% に到達するのに 15 時間かかりました...

stream_get_line、fgets、およびsedのexecを使用して、ここで提案されているソリューションのいくつかを試しました。私は、この質問に立ち寄った他の人と共有すると思った別のアプローチに行き着きました.

ファイルを分割してください!:-)

私の freebsd ボックス (Linux などにも存在します) には、'split' という名前のコマンド ライン ユーティリティがあります。

使用法: 分割 [-l 行数] [-a 接尾辞の長さ] [ファイル [接頭辞]]
       split -b byte_count[K|k|M|m|G|g] [-a suffix_length] [file [prefix]]
       split -n chunk_count [-a suffix_length] [file [prefix]]
       split -p pattern [-a suffix_length] [file [prefix]]

だから私は走った:

分割 -l 25000 -a 3 /data/var/myfile.log /data/var/myfile-log/

その後、/data/var/myfile-log/ ディレクトリに 5608 個のファイルがあり、次のようなコマンドで一度に 1 つずつ処理できます。

php -f do-some-work.php /data/var/myfile-log/*
于 2011-04-05T12:45:10.833 に答える
0

さて、パフォーマンスの問題です。明らかに、あるべきではない場合に何かが 2 次になるか、それ以上に言えば、一定時間であるべき何かが、これまでに処理されたレコードの数に比例しているように見えます。最初の質問は、問題を示す最小限のコード スクラップは何かということです。ファイルを1行ずつ読む以外はすべてコメントアウトしたときに、同じ問題のある動作が発生するかどうかを知りたいです。もしそうなら、その問題のない言語が必要になります。(たくさんあります。) とにかく、予想される時間特性を確認したら、タイミングが狂うまでステートメントを1つずつ追加し直します。これで問題が特定されます。

タイミングを取得するために何かを装備しました。それらを単独で 15000 回程度実行して、問題が発生しないことを確認してください。

于 2010-08-17T11:33:40.550 に答える