看板 Perl 關於我們 聯絡資訊
請問各位,我現在有一筆約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放在一起比較,要取回完整的標題時, 整個執行的速度慢了相當多! 請問是不是我寫的程式碼裡有問題?應該要怎麼修改會比較好? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.116.25.64 ※ 文章網址: http://www.ptt.cc/bbs/Perl/M.1395997757.A.123.html
LiloHuang:由於第二個 while loop 會將整個 %whole 都拜訪一次 03/28 17:54
LiloHuang:當 %whole 很大時,時間複雜度會大幅度的提高 03/28 17:54
LiloHuang:如果只是需要把完整標題拿出來,可以考慮多記憶一些內容 03/28 17:55
LiloHuang:例如改成 $query_hash{$name} = [最大數, 完整的一行]; 03/28 17:56
LiloHuang:這樣在跑第二個迴圈時,就不需要對 %whole 從頭查到尾 03/28 17:57
LiloHuang:或者把每一行的內容放在單獨的 array 裡面 03/28 18:04
LiloHuang:$query_hash{$name} = [最大數, 完整資料的索引]; 03/28 18:05
chong:謝謝你的建議,我再嘗試看看。 03/28 21:57
rkcity:是Lilo大!! (膜拜 03/29 17:13
chong:速度差非常多,舊的用了數小時,新的瞬間秒殺! 03/31 11:10
hhs66317:Lilo的思路值得學習﹐讚~~ 06/01 10:09