Performance 提高解析fastq的速度

Performance 提高解析fastq的速度,performance,perl,parsing,fastq,Performance,Perl,Parsing,Fastq,@用相同的代码求解C#的速度是原来的两倍 我正在用perl解析一个phred33 fastq文件,这需要相当长的时间(大约15分钟)。fastq文件大约为3千兆位。 有什么合理的方法可以让这更快 $file=shift; open(FILE,$file); open(FILEFA,">".$file.".fa"); open(FILEQA,">".$file.".qual"); while($line=<FILE>) { chomp($line); if(

@用相同的代码求解C#的速度是原来的两倍

我正在用perl解析一个phred33 fastq文件,这需要相当长的时间(大约15分钟)。fastq文件大约为3千兆位。 有什么合理的方法可以让这更快

$file=shift;
open(FILE,$file);
open(FILEFA,">".$file.".fa");
open(FILEQA,">".$file.".qual");
while($line=<FILE>)
{
    chomp($line);
    if($line=~m/^@/)
    {


    $header=$line;
    $header =~ s/@/>/g;
    $seq=<FILE>;
    chomp($seq);
    $nothing=<FILE>;
    $nothing="";
    $fastq=<FILE>;

    print FILEFA $header."\n";
    print FILEFA $seq."\n";
    $seq="";
    print FILEQA $header."\n";

        @elm=split("",$fastq);
        $i=0;
        while(defined($elm[$i]))
        {
            $Q = ord($elm[$i]) - 33;
            if($Q!="-23")
            {
            print FILEQA $Q." ";
            }
            $i=$i+1;
        }
        print FILEQA "\n";
    }
}
print $file.".fa\n";
print $file.".qual\n";
$file=shift;
打开(文件,$FILE);
打开(FILEFA“>”$file“.fa”);
打开(FILEQA,“>”$file.“.qual”);
而($line=)
{
chomp($line);
如果($line=~m/^@/)
{
$header=$line;
$header=~s/@/>/g;
$seq=;
chomp($seq);
$nothing=;
$nothing=“”;
$fastq=;
打印FILEFA$标题。“\n”;
打印文件fa$seq。“\n”;
$seq=“”;
打印文件QA$标题。“\n”;
@elm=拆分(“,$fastq”);
$i=0;
而(定义为($elm[$i]))
{
$Q=ord($elm[$i])-33;
如果($Q!=“-23”)
{
打印文件QA$Q.“”;
}
$i=$i+1;
}
打印文件QA“\n”;
}
}
打印$file。“.fa\n”;
打印$file。“.qual\n”;

这里几乎没有使用CPU。它是IO绑定的,所以大部分时间都是通过3GB进行读取的。可以进行微优化(和其他清理)

首先,始终使用
严格使用;使用警告

主要代码是

my @elm = split(//, $fastq);
my $i=0;
while(defined($elm[$i])) {
    my $Q = ord($elm[$i]) - 33;
    if($Q!="-23") {
        print FILEQA $Q." ";
    }
    $i=$i+1;
}
if($Q!=“-23”)
的目的是检查字符是否为换行符,如果您选择了
chomp($fastq),则不必这样做。(关于
-23
的引号是什么?!)

使用
while
循环只会使事情复杂化。当迭代次数已知时,使用for循环

chomp($fastq);
for (split(//, $fastq)) {
    print FILEQA (ord($_)-33)." ";
}
print FILEQA "\n";
这可能有助于将其彻底改变

chomp($fastq);
print FILEQA join(' ', map ord($_)-33, split //, $fastq), "\n";
仔细想想,还不够彻底:)

但是,我们预先计算了这些翻译又有什么意义呢?这样我们就不必重复调用sub(代码)

my %map = map { chr($_) => ($_-33)." " } 0x00..0xFF;

$fastq =~ s/(.)/$map{$1}/g;
print FILEQA $fastq;

经过进一步清理,我们得到:

use strict;
use warnings;

my %map = map { chr($_) => ($_-33)." " } 0x00..0xFF;

my $file = shift;

my $fa_file   = "$file.fa";
my $qual_file = "$file.qual";

open(my $FILE,   '<', $file     ) or die $!;
open(my $FILEFA, '>', $fa_file  ) or die $!;
open(my $FILEQA, '>', $qual_file) or die $!;

while (my $header = <$FILE>) {
    next if $header !~ /^@/;

    my $seq = <$FILE>;
    <$FILE>;
    my $fastq = <$FILE>;

    $header =~ s/@/>/g;
    $fastq =~ s/(.)/$map{$1}/g;

    print $FILEFA $header;
    print $FILEFA $seq;

    print $FILEQA $header;
    print $FILEQA $fastq;
}

print "$fa_file\n";
print "$qual_file\n";
使用严格;
使用警告;
我的%map=map{chr($\u)=>($\ u33)。“}0x00..0xFF;
我的$file=shift;
my$fa_file=“$file.fa”;
my$qual_file=“$file.qual”;
打开(my$文件,,$fa_文件)或死亡$!;
打开(我的$FILEQA,'>',$qual_文件)或死亡$!;
while(我的$header=){
下一个if$header!~/^@;
我的$seq=;
;
我的$fastq=;
$header=~s/@/>/g;
$fastq=~s/()/$map{$1}/g;
打印$FILEFA$标题;
打印$FILEFA$seq;
打印$FILEQA$标题;
打印$FILEQA$fastq;
}
打印“$fa_文件\n”;
打印“$qual_文件\n”;

这里几乎没有使用CPU。它是IO绑定的,所以大部分时间都是通过3GB进行读取的。可以进行微优化(和其他清理)

首先,始终使用
严格使用;使用警告

主要代码是

my @elm = split(//, $fastq);
my $i=0;
while(defined($elm[$i])) {
    my $Q = ord($elm[$i]) - 33;
    if($Q!="-23") {
        print FILEQA $Q." ";
    }
    $i=$i+1;
}
if($Q!=“-23”)
的目的是检查字符是否为换行符,如果您选择了
chomp($fastq),则不必这样做。(关于
-23
的引号是什么?!)

使用
while
循环只会使事情复杂化。当迭代次数已知时,使用for循环

chomp($fastq);
for (split(//, $fastq)) {
    print FILEQA (ord($_)-33)." ";
}
print FILEQA "\n";
这可能有助于将其彻底改变

chomp($fastq);
print FILEQA join(' ', map ord($_)-33, split //, $fastq), "\n";
仔细想想,还不够彻底:)

但是,我们预先计算了这些翻译又有什么意义呢?这样我们就不必重复调用sub(代码)

my %map = map { chr($_) => ($_-33)." " } 0x00..0xFF;

$fastq =~ s/(.)/$map{$1}/g;
print FILEQA $fastq;

经过进一步清理,我们得到:

use strict;
use warnings;

my %map = map { chr($_) => ($_-33)." " } 0x00..0xFF;

my $file = shift;

my $fa_file   = "$file.fa";
my $qual_file = "$file.qual";

open(my $FILE,   '<', $file     ) or die $!;
open(my $FILEFA, '>', $fa_file  ) or die $!;
open(my $FILEQA, '>', $qual_file) or die $!;

while (my $header = <$FILE>) {
    next if $header !~ /^@/;

    my $seq = <$FILE>;
    <$FILE>;
    my $fastq = <$FILE>;

    $header =~ s/@/>/g;
    $fastq =~ s/(.)/$map{$1}/g;

    print $FILEFA $header;
    print $FILEFA $seq;

    print $FILEQA $header;
    print $FILEQA $fastq;
}

print "$fa_file\n";
print "$qual_file\n";
使用严格;
使用警告;
我的%map=map{chr($\u)=>($\ u33)。“}0x00..0xFF;
我的$file=shift;
my$fa_file=“$file.fa”;
my$qual_file=“$file.qual”;
打开(my$文件,,$fa_文件)或死亡$!;
打开(我的$FILEQA,'>',$qual_文件)或死亡$!;
while(我的$header=){
下一个if$header!~/^@;
我的$seq=;
;
我的$fastq=;
$header=~s/@/>/g;
$fastq=~s/()/$map{$1}/g;
打印$FILEFA$标题;
打印$FILEFA$seq;
打印$FILEQA$标题;
打印$FILEQA$fastq;
}
打印“$fa_文件\n”;
打印“$qual_文件\n”;

我想如果我站在你的立场上,我可能会启动cachegrind…快速搜索:你也可以尝试阅读
:raw
:请看,也许我对perl了解不多——does
$nothing=将整个文件作为数组读入?也许你正在反复阅读整个文件?@FrankFarmer谢谢你的链接,我确实读过,但仍然不知道如何修复我的代码$nothing=读取一行:)
$nothing=$“无”包含两个不必要的赋值。只要使用
。我想如果我站在你的立场上,我可能会启动cachegrind…快速搜索:你也可以尝试阅读
:raw
:也可以看到,也许我对perl了解不多——does
$nothing=将整个文件作为数组读入?也许你正在反复阅读整个文件?@FrankFarmer谢谢你的链接,我确实读过,但仍然不知道如何修复我的代码$nothing=读取一行:)
$nothing=$“无”包含两个不必要的赋值。只需使用
@caseyr547,它可能不会产生重大区别,正如我所解释的。也许您可以使用
sysread
在同一时间读取更大的数据块(比如64KB),然后从中提取行(即使用更大的缓冲区进行您自己的缓冲)。Perl 5.14使用8K读取器(并在构建时使其可配置),而较旧的Perl使用4K读取器,因此Perl 5.14实际上会有所帮助fast@caseyr547,这可能不会有什么大区别,正如我所解释的。也许您可以使用
sysread
,在同一时间读取更大的数据块(比如64KB),然后从中提取行(即使用更大的缓冲区进行您自己的缓冲)。Perl 5.14使用8K读取器(并在构建时使其可配置),而较旧的Perl使用4K读取器,因此Perl 5.14实际上会有所帮助