2012-04-24 4 views
0

@solved C 번호를 구문 분석의 속도를 향상 난 펄에서 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

많은 펄을 모른다 -'$ 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 주위에 따옴표와 함께 무엇?!)을 while 루프를 사용

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

는 일을 복잡하게한다. 반복 횟수를 알고있는 경우 for 루프를 사용하십시오.

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

내면을 뒤집어 놓는 것이 도움이 될 수 있습니다.

chomp($fastq); 
print FILEQA join(' ', map ord($_)-33, split //, $fastq), "\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