Улучшить скорость разбора fastq
@solved C# с тем же кодом в два раза быстрее
Я анализирую файл phred33 fastq в Perl, и это занимает значительное количество времени (порядка 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";
1 ответ
Там рядом нет процессора используется здесь. это связано с вводом-выводом, поэтому самое время прочитать 3ГБ. Есть микрооптимизации (и другие очистки), которые могут быть сделаны.
Во-первых, всегда используйте use strict; use warnings;
,
Основной код
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
?!)
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";
Это может помочь немного вывернуть это наизнанку.
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";