我是编程的初学者,不仅是perl!请让我知道需要更改的内容或如何进行更改。
需要优化perl代码以使其运行更快。对于一个大约500MB的文件(其中包含300万行)的测试运行,运行时间为28分钟。
我知道一个工具可以在15分钟内处理3900万行,但是我想在不使用该工具的情况下在命令提示符下运行该工具。
早些时候,我使用Date :: Manip和Date :: Parse并转到DateTime,以为它应该更快。
我的方法是,如果日期是ISO-8601(即YYYY-MM-DD),而我们不需要验证它们,则可以按字典顺序进行比较(即lt和gt运算符)。
我已经尝试了“>”和“ 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);
这里有两个半大的性能问题:
parse_datetime
返回一个DateTime对象。Perl的面向对象意味着大量的开销。因为您的模式定义良好,所以我们可以自行分析并删除所有面向对象的方向。要将日期字符串解析为可排序的表示形式,我们只需将各个部分重新排序为字符串即可:
# %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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句