【发布时间】:2019-09-03 17:05:26
【问题描述】:
我在 Perl6 中有一个基本脚本,它运行非常很慢,比精确的 perl5 翻译慢大约 30 倍。
CONTROL {
when CX::Warn {
note $_;
exit 1;
}
}
use fatal;
role KeyRequired {
method AT-KEY (\key) {
die "Key {key} not found" unless self.EXISTS-KEY(key);
nextsame;
}
}
for dir(test => /^nucleotide_\d**2_\d**2..3\.tsv$/) -> $tsv {
say $tsv;
my $qqman = $tsv.subst(/\.tsv$/, '.qqman.tsv');
my $out = open $qqman, :w;
put "\t$qqman";
my UInt $line-no = 0;
for $tsv.lines -> $line {
if $line-no == 0 {
$line-no = 1;
$out.put(['SNP', 'CHR', 'BP', 'P', 'zscore'].join("\t"));
next
}
if $line ~~ /.+X/ {
next
}
$line-no++;
my @line = $line.split(/\s+/);
my $chr = @line[0];
my $nuc = @line[1];
my $p = @line[3];
my $zscore = @line[2];
my $snp = "'rs$line-no'";
$out.put([$snp, $chr, $nuc, $p, $zscore].join("\t"));
#$out.put();
}
last
}
这是 Perl5 的 while 的惯用语。
这是一个非常简单的脚本,它只改变文件中的文本列。这个 Perl6 脚本在 30 分钟内运行。 Perl5 翻译运行时间为 1 分钟。
我已尝试阅读 Using Perl6 to process a large text file, and it's Too Slow.(2014-09) 和 Perl6 : What is the best way for dealing with very big files?,但在这里我没有看到任何可以帮助我的东西 :(
我正在运行Rakudo version 2018.03 built on MoarVM version 2018.03
implementing Perl 6.c.
我意识到 Rakudo 还没有成熟到 Perl5 的水平(我希望如此),但是我怎样才能让它在更合理的时间范围内逐行读取文件?
【问题讨论】:
-
是什么让您认为逐行读取文件是脚本的瓶颈?
-
@ugexe 数学很简单。否则我没想到会花很长时间。但是,我将精简脚本以验证逐行实际上是瓶颈。
-
不仅仅是简单的数学运算。有 IO(打开/读取文件)、赋值、正则表达式解析和类型约束检查。
-
看来您可以将
$line ~~ /.+X/更改为$line.index("X"),因为您没有捕获任何内容。 -
如果您处理多个文件,您可以尝试通过将 for 更改为 map 来并行处理它们,然后使用 hyper or race。
标签: raku