0

これは、SQLからデータをフェッチする単純なperlスクリプトです。データの読み取りとファイルOUTFILEへの書き込み、および10000行ごとに画面上のデータの印刷。

私が興味を持っていることの1つは、画面へのデータの印刷が非常に速く(30秒で)終了することですが、ファイルへのデータのフェッチと書き込みは非常に遅く(30分後)終了します。

データ量は多くありません。出力ファイルのサイズは100Mバイト未満です。

while ( my ($a,$b) = $curSqlEid->fetchrow_array() ) 
{
    printf OUTFILE ("%s,%d\n", $a,$b);
    $counter ++;
    if($counter % 10000 == 0){
        printf ("%s,%d\n", $a,$b);
    }
}  
$curSqlEid->finish();
$dbh->disconnect();
close(OUTFILE);
4

3 に答える 3

3

あなたはバッファリングに苦しんでいます。

STDERR以外のハンドルはデフォルトでバッファリングされ、ほとんどのハンドルはブロックバッファリングを使用します。つまり、Perlは、システムに何かを送信する前に、書き込むデータが8KB*になるまで待機します。

STDOUTは特別です。が端末に接続されている場合(そしてその場合のみ)、別の種類のバッファリングを使用します。ラインバッファリングです。ラインバッファリングを使用する場合、書き込むデータで改行が検出されるたびにデータがフラッシュされます。

あなたはこれを実行することで見ることができます

$ perl -e'print "abc"; print "def"; sleep 5; print "\n"; sleep 5;'
[ 5 seconds pass ]
abcdef
[ 5 seconds pass ]

$ perl -e'print "abc"; print "def"; sleep 5; print "\n"; sleep 5;' | cat
[ 10 seconds pass ]
abcdef

解決策は、バッファリングをオフにすることです。

use IO::Handle qw( );  # Not needed on Perl 5.14 or later
OUTFILE->autoflush(1);

* —デフォルトは8KBです。Perlのコンパイル時に設定できます。5.14までは構成不可能な4KBでした。

于 2012-04-26T20:57:03.400 に答える
0

スクリプトの実行中およびコンソールでの表示中に、出力ファイルサイズが0として表示されていると思います。それで行かないでください。ファイルサイズは、スクリプトが終了した後にのみ表示されます。これは、出力バッファリングが原因です。

とにかく、遅延は30分ほど大きくすることはできません。スクリプトが完了すると、出力ファイルのデータが表示されます。

于 2012-04-27T04:25:52.920 に答える
0

私はさまざまなことを試しましたが、最終的な結論は、pythonとperlは基本的にDBとはデータフローの処理が異なるということです。perlのように見えますが、データがDBから転送されている間、データを1行ずつ処理することができます。ただし、Pythonでは、データ全体がサーバーからダウンロードされて処理されるまで待機する必要があります。

于 2013-01-08T05:58:00.150 に答える