5

非常に大きなログ ファイルを書き出す perl スクリプトがあります。現在、「従来の」Perl の方法でファイルを書き出します。

open FILE, ">", 'log.txt';
print FILE $line;
.....
close FILE;

File::Slurpについて、ファイルを読み込むときに良いことや、実行時間を大幅に改善する方法について多くのことを聞いてきました。私の質問は、File::Slurp を使用すると、ログ ファイルの書き出しが速くなるでしょうか? 私が尋ねるのは、perl でファイルを書き出すのは非常に簡単に思えるからです。File::Slurp がどのようにそれを本当に最適化できるのか、私にはわかりません。

4

2 に答える 2

9

ユーティリティは、特定のFile::Slurp状況下では、同等のストリーミング実装よりも全体的にわずかに高速になる場合がありますが、ファイル I/O は、メモリと CPU 速度のみに基づくものよりも非常に遅いため、ほとんどの場合、リソースが制限されます。

ランタイムを大幅に改善File::Slurpできるという主張は聞いたことがありません。それがより効率的な解決策であると私が考える唯一の方法は、プログラムがファイルへのランダムアクセスを必要とするか、複数回読み取る必要がある場合です。データは一度にすべてメモリ内にあるため、データにアクセスするためのオーバーヘッドはありませんが、この場合、速度への影響がほとんどなく、メモリのオーバーヘッドがはるかに少ない状態で、すべてのデータが同時に利用可能であるかのように見えるものを好みます。Tie::File

実際、 を呼び出すとread_file、プロセスがユーザーにとって非常に遅く見える場合があります。ファイルが非常に大きい場合、すべてを読み取って行に分割するのにかかる時間は、処理を開始する前に明確な遅延になる可能性がありますが、ファイルを開いて最初の行を読み取ると、通常は瞬時に表示されます。

プログラム終了後も同様です。データをディスク ブロックに結合し、それをファイルにページ アウトする への呼び出しはwrite_file、単にファイルを閉じるよりも大幅に時間がかかります。

一般に、従来のストリーミング出力方法が推奨されます。速度への影響はほとんどまたはまったくなく、何らかの理由でディスクに書き込めないことを発見する前に大量のデータがメモリに蓄積されるまで待つのではなく、データを段階的に保存することでデータ損失を回避します。

私のアドバイスは、File::Slurpランダムアクセスがプログラムコードを大幅に簡素化できる小さなファイルがある場合は、使用を予約することです。それでも何も問題ない

my @data = do {
  open my $fh, '<', 'my_file' or die $!;
  <$fh>;
};

入力用、または

open my $fh, '>', 'out_file' or die $!;
print { $fh } for @data;

出力用。特にあなたの場合、非常に大きなログファイルを扱っている場合、ストリーミング出力方法に固執する必要があることに疑問の余地はないと思います

于 2012-09-03T12:03:32.063 に答える
8

File::Slurp主に便利な機能です。通常のopen, while read/write,closeコードを書く代わりに、read_filewrite_file.

ただし、独自のコードよりも高速であることはわかりません。これは、C ではなく Perl でコーディングされています。また、配列バリアントを使用する場合、write_file $file_name, @lines最初にすべての配列行を 1 つのスカラーに結合してから書き出すため、メモリに関して少し非効率になる可能性があります。

ただし、syswriteバッファリングされた書き込みの代わりに使用します。これは、有効期間中にファイル ハンドルにアクセスする唯一の関数であるため、安全に実行できます。そうです、それが原因でより速いかもしれません。

于 2012-09-03T06:40:41.163 に答える