[问题] 执行效率

楼主: chong (CW)   2014-03-28 17:09:14
请问各位,我现在有一笔约10万笔基因序列的资料,
部分内容如下:
>Locus_41_Transcript_1/7_Confidence_0.385_Length_892
>Locus_41_Transcript_2/7_Confidence_0.385_Length_920
>Locus_41_Transcript_3/7_Confidence_0.577_Length_1466
>Locus_41_Transcript_4/7_Confidence_0.577_Length_1431
>Locus_41_Transcript_5/7_Confidence_0.538_Length_1359
>Locus_41_Transcript_6/7_Confidence_0.577_Length_1431
>Locus_41_Transcript_7/7_Confidence_0.577_Length_1431
>Locus_42_Transcript_1/1_Confidence_1.000_Length_2058
>Locus_43_Transcript_1/10_Confidence_0.312_Length_1094
>Locus_43_Transcript_2/10_Confidence_0.469_Length_1565
以locus_41为例,它有7笔资料,最后的数字是该序列的长度,
像这样的资料,我只要取长度最大的一笔。
若是locus_42,因为只有一笔,所以不用取舍,直接使用。
我写的程式码如下:
#!/usr/bin/env -perl -w
use Bio::DB::Fasta;
open my $query, "<", $ARGV[0] or die "$!";
my (%query_hash, %whole);
while (my $line = <$query>) {
chomp ($line);
if ($line =~ /^>/) {
my @line = split (/_/, $line);
my $name = substr($line[0], 1)."_$line[1]";
$whole{substr($line, 1)} = "$name $line[7]";
#把所有内容皆读入hash。
if (! exists $query_hash{$name}) {
$query_hash{$name} = $line[7];
}
elsif ($query_hash{$name} <= $line[7]) {
$query_hash{$name} = $line[7];
#保留数字最大的一笔
}
}
}
close $query;
my $db = Bio::DB::Fasta->new($ARGV[1]);
my @query_hash_result;
foreach my $result (keys %query_hash) {
my $query_whole = "$result $query_hash{$result}";
while (my ($key, $value) = each (%whole)) {
if ($value eq $query_whole) {
#重新取得完整的标题,用以取得DNA序列资料。
my $query_fasta = $db->get_Seq_by_id($key);
my $query_seq = $query_fasta->seq;
print ">$query_fasta\n";
print "$query_seq\n";
}
}
}
现在遇到的状况是,如果我只执行上半部的程式码,即把标题资料读入hash,
没什么问题,不会用很多时间。
在%query_hash里,大约会取得7万笔资料。
而%whole里,大约有14万笔资料。
但,当我把2个hash放在一起比较,要取回完整的标题时,
整个执行的速度慢了相当多!
请问是不是我写的程式码里有问题?应该要怎么修改会比较好?
谢谢
作者: LiloHuang (十年一刻)   2014-03-28 17:54:00
由于第二个 while loop 会将整个 %whole 都拜访一次当 %whole 很大时,时间复杂度会大幅度的提高如果只是需要把完整标题拿出来,可以考虑多记忆一些内容例如改成 $query_hash{$name} = [最大数, 完整的一行];这样在跑第二个循环时,就不需要对 %whole 从头查到尾或者把每一行的内容放在单独的 array 里面$query_hash{$name} = [最大数, 完整资料的索引];
楼主: chong (CW)   2014-03-28 21:57:00
谢谢你的建议,我再尝试看看。
作者: rkcity (喵。罐頭)   2014-03-29 17:13:00
是Lilo大!! (膜拜
楼主: chong (CW)   2014-03-31 11:10:00
速度差非常多,旧的用了数小时,新的瞬间秒杀!
作者: hhs66317 (六子)   2014-06-01 10:09:00
Lilo的思路值得学习﹐赞~~

Links booklink

Contact Us: admin [ a t ] ucptt.com