[問題] 執行效率

作者: 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