在Perl6中逐行读取文件,怎么习惯?

con*_*con 7 perl6

我在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
}
Run Code Online (Sandbox Code Playgroud)

这是Perl5的习惯用法while

这是一个非常简单的脚本,它仅更改文件中的文本列。该Perl6脚本在30分钟内运行。Perl5转换在1分钟内运行。

我已经尝试阅读使用Perl6处理大型文本文件,但是它太慢了。(2014-09)Perl6:处理超大文件的最佳方法是什么?但我看不到有什么可以帮助我的地方:(

我在跑 Rakudo version 2018.03 built on MoarVM version 2018.03 implementing Perl 6.c.

我意识到Rakudo还没有达到Perl5的水平(但是,我希望如此),但是如何在更合理的时间范围内逐行读取文件呢?

Bra*_*ert 10

我会改变很多事情。

  • /.+X/可以简化为公正/.X/甚至$line.substr(1).contains('X')
  • $line.split(/\s+/) 可以简化为 $line.words
  • $tsv.subst(/\.tsv$/, '.qqman.tsv') 可以简化为 $tsv.substr(*-4) ~ '.qqman.tsv'
  • uint 代替 UInt
  • given .head {} 代替 for … {last}
given dir(test => /^nucleotide_\d**2_\d**2..3\.tsv$/).head -> $tsv {
    say $tsv;
    my $qqman = $tsv.substr(*-4) ~ '.qqman.tsv';
    my $out = open $qqman, :w;
    put "\t$qqman";

    my uint $line-no = 0;
    for $tsv.lines -> $line {
        FIRST {
            $line-no = 1;
            $out.put(('SNP', 'CHR', 'BP', 'P', 'zscore').join("\t"));
            next
        }
        next if $line.substr(1).contains('X');

        ++$line-no;

        my ($chr,$nuc,$zscore,$p) = $line.words;

        my $snp = "'rs$line-no'";
        $out.put(($snp, $chr, $nuc, $p, $zscore).join("\t"));
        #$out.put();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @con:`/.+ X /`/ .X /`和`$ line.substr(1).contains('X')`在功能上是相同的。/.* X /`/ X /`和$ line.contains('X')'在功能上是相同的。(.substr(1)是这样,因此它与行首的X不匹配。) (3认同)
  • 尽管OP主要关注速度,但他们也简短地提到了惯用性,因此,对于在我打开的文件中逐行处理的问题,我一直在寻找`$ tsv.IO.lines-> $ line格式。 `是一种更好的方法。尽管功能相同,但$ out.put的同上:<SNP CHR BP P zscore> .join(“ \ t”)`。 (3认同)