基本上,我有一个脚本来为具有相应基因ID的COG创建哈希:
# Open directory and get all the files in it
opendir(DIR, "/my/path/to/COG/");
my @infiles = grep(/OG-.*\.fasta/, readdir(DIR));
closedir(DIR);
# Create hash for COGs and their corresponding gene IDs
tie my %ids_for, 'Tie::IxHash';
if (! -e '/my/path/to/COG/COG_hash.ref') {
for my $infile (@infiles) {
## $infile
%ids_for = (%ids_for, read_COG_fasta($infile));
}
## %ids_for
store \%ids_for, '/my/path/to/COG/COG_hash.ref';
}
my $id_ref = retrieve('/my/path/to/COG/COG_hash.ref');
%ids_for = %$id_ref;
## %ids_for
问题不是(至少我认为)它不起作用,但是由于某种原因它非常慢。当我尝试对其进行测试时,要花费几周的时间才能得到实际的结果。某种程度上说,哈希创建的确真的很慢,而且我敢肯定,有某种方法可以更好地对其进行优化,以使其更快地工作。
理想情况下,路径应该是脚本的输入,这样就不必在路径更改的情况下不断更改脚本。
如果有一种方法可以查看哈希创建的进度,也可能很棒,就像它表明已完成25%,50%完成,75%完成并最终100%完成一样。关于最后一点,我已经看到类似use Term::ProgressBar
的内容,但是我不确定在这种情况下是否合适。
您真的需要Tie::IxHash
吗?
此外,我怀疑您的罪魁祸首是这条线:
for my $infile (@infiles) {
## $infile
%ids_for = (%ids_for, read_COG_fasta($infile));
}
要向哈希添加键,您要创建当前键/值对的列表,添加新的对,然后将其全部分配回哈希。
如果您从read_COG_fasta
中获取结果并一次添加一个键会怎样?
for my $infile (@infiles) {
my %new_hash = read_COG_fasta($infile);
foreach my $key ( keys %new_hash ) {
$ids_for{$key} = $new_hash{$key};
}
}
关于进度,当我试图找出一些东西时,我通常会有这样的东西:
use v5.26;
my $file_count = @files;
foreach my $n ( 0 .. $#files ) {
say "[$n/$file_count] Processing $file[$n]";
my %result = ...;
printf "\tGot %d results", scalar keys %hash; # v5.26 feature!
}
您可以使用返回的键来做同样的事情,以便可以跟踪大小。