0

私はperlだけでなくプログラミングの初心者です!何を変更する必要があるか、またはこれを行うにはどうすればよいか教えてください。

より高速に実行するには、perl コードを最適化する必要があります。300 万行を含む約 500MB のファイルをテスト実行すると、実行時間は 28 分です。

15 分で 3900 万行を処理するツールを知っていますが、ツールに頼らずにコマンド プロンプトでこれを実行したいと考えています。

以前は、Date::Manip と Date::Parse を使用していましたが、DateTime の方が速いはずだと考えて、DateTime に移行しました。

私のアプローチは、日付が ISO-8601 (つまり、YYYY-MM-DD) であり、それらを検証する必要がない場合、辞書式に比較できます (つまり、lt および gt 演算子)。

  • 入力ファイルの日付形式は 2013 年 7 月 18 日 13:45:49 です。
  • 入力ファイルサイズ 42GB。
  • 行数 3900 万。
  • 列区切り記号 : |~|
  • プラットフォーム: GNU/リナックス

">" と "gt" を試しましたが、ランタイムに違いはありませんでした。

Code snippet:

use DateTime::Format::Strptime;

my $idate = "07/17/2013 00:00:00";

my $Strp = DateTime::Format::Strptime->new(
                   pattern     => '%m/%d/%Y %H:%M:%S',
                  );

my $inputdt = $Strp->parse_datetime($idate);

open (FILE,"myinputfile.dat") or die "could not input File\n";
while (defined(my $line = <FILE>)) {
    my @chunks = split '[|]~[|]', $line;
    my $fdate = $Strp->parse_datetime($chunks[6]);
    if ( $fdate > $inputdt) {
    open(FILEOUT, ">>myoutputfile.dat") or die "Could not write\n";
    print FILEOUT "$line";
                         }
}
close(FILE);
close (FILEOUT);
4

1 に答える 1

2

ここには 2 つ半の大きなパフォーマンスの問題があります。

  1. 反復ごとに出力ファイルを開きます。ループの前に一度開くだけです。
  2. parse_datetimeDateTime オブジェクトを返します。Perl でのオブジェクト指向は、かなりのオーバーヘッドを意味します。パターンが明確に定義されているため、解析を自分で行い、すべてのオブジェクト指向を削除できます。
  3. GB 範囲のファイルを読み取るには、少し時間がかかります。これを高速化するには、ハードウェアをアップグレードします (SSD など)。

日付文字列を解析してソート可能な表現にするために、さまざまな部分を文字列に並べ替えるだけです。

# %m/%d/%Y %H:%M:%S → %Y/%m/%d %H:%M:%S
$fdate =~ s{^ ([0-9]{2} / [0-9]{2}) / ([0-9]{4}) }{$2/$1}x;

if ($fdate gt $inputdate) { ... }

これはコードにつながります

use strict; use warnings;

use constant DATE_FIELD => shift @ARGV;

my $inputdate = shift @ARGV;
$inputdate =~ s{^ ([0-9]{2} / [0-9]{2}) / ([0-9]{4}) }{$2/$1}x;

<>; # remove the header line

while (<>) {
    my $filedate = (split /\|~\|/, $_, DATE_FIELD + 2)[DATE_FIELD];
    $filedate =~ s{^ ([0-9]{2} / [0-9]{2}) / ([0-9]{4}) }{$2/$1}x;
    print if $filedate gt $inputdate;
}

入力と出力、および開始日は、コマンド ラインで指定します。

./script 6 '07/17/2013 00:00:00' myinputfile.dat >>myoutputfile.dat
于 2013-07-18T13:39:09.750 に答える