2012-04-24 9 views
0

@solvedのC#の構文解析の速度を向上させる、私はPerlでphred33のFASTQファイルを解析していますし、それが(15分程度)かなりの時間を取っているは、同じコードでFASTQ

倍の速度です。 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"; 
+0

、私はおそらくcachegrind ... –

+0

を起動したいいくつかの簡単なグーグルます。http ://www.biostars.org/post/show/5005/ngs-huge-fastq-file-parsing-which-language-for-good-efficiency/あなたは ':raw'から読むこともできます:http:// www.perlmonks.org/?node_id=837624 http://stackoverflow.com/questions/1349604/what-is-the-fastest-way-to-read-10-gb-file-from-the-diskを参照してください。おそらくhttp://stackoverflow.com/questions/1052765/linux-perl -mmap-performance –

+0

私は多くのperlを知らないです - '$ nothing = ;'ファイル全体を配列として読み込みますか?おそらくあなたはファイル全体を繰り返し読んでいるでしょうか? –

答えて

1

ここではCPUが使用されていません。それはIOバウンドなので、ほとんどの場合3GBを読み込む時間です。行うことができるマイクロ最適化(および他のクリーンアップ)があります。

まず、常にuse strict; use warnings;を使用してください。

メインコードはif($Q!="-23")の目的は、文字はあなたがchomp($fastq);をした場合の対処する必要はない改行、あるかどうかを確認するために

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; 
} 

です。 (-23の前後に引用符とは何ですか?!)

chomp($fastq); 
my @elm = split(//, $fastq); 
my $i=0; 
while(defined($elm[$i])) { 
    my $Q = ord($elm[$i]) - 33; 
    print FILEQA $Q." "; 
    $i=$i+1; 
} 
print FILEQA "\n"; 

物事を複雑にwhileループを使用します。既知の反復回数がある場合は、forループを使用します。

chomp($fastq); 
for (split(//, $fastq)) { 
    print FILEQA (ord($_)-33)." "; 
} 
print FILEQA "\n"; 

これを内側に回すのに役立つかもしれません。

考え直しで ​​

、ない内部のうち、十分な:)

$fastq =~ s/(.)/(ord($1)-33) . " "/eg; 
print FILEQA $fastq; 

しかし、それは我々が翻訳を事前に計算?その後、サブコード(/eコード)を繰り返し呼び出す必要はありません。

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"; 
+0

ありがとう私は今それをテストしています:) –

+0

@ caseyr547、私は説明したように、おそらく大きな違いはありません。 – ikegami

+1

おそらく、 'sysread'を使ってより大きいデータブロック(例えば64KB)を読んでから、それから行を抽出します(つまり、より大きなバッファで独自のバッファリングを行います)。 Perl 5.14は8Kのリーダーを使用し(ビルド時に設定可能にした)、古いPerlでは4Kのリーダーを使用していたので、Perl 5.14が実際に役に立ちました。 – ikegami

関連する問題