Почему моя программа T ie :: IxHa sh занимает много времени? - PullRequest
0 голосов
/ 04 марта 2020

По сути, у меня есть скрипт для создания ха sh для 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

Проблема не в том, что он не работает (по крайней мере, я так думаю), но это очень медленно по какой-то причине. Когда я пытался протестировать его, мне потребовались недели, чтобы получить реальный результат. Каким-то образом создание ha sh действительно очень медленное, и я уверен, что есть способ оптимизировать его, чтобы он работал быстрее.

В идеале пути должны быть входными данными сценария, чтобы не было необходимости постоянно менять сценарий в случае изменения пути.

Было бы также хорошо, если бы способ увидеть прогресс создания ха sh, например, показать, что оно выполнено на 25%, выполнено на 50%, выполнено на 75% и в конечном итоге на 100%. Что касается этого последнего пункта, я видел такие вещи, как use Term::ProgressBar, но я не уверен, будет ли это уместно в этом случае.

1 Ответ

4 голосов
/ 04 марта 2020

Вам действительно нужно Tie::IxHash?

Кроме этого, я подозреваю, что ваш виновник - это набор строк:

for my $infile (@infiles) {
    ## $infile
    %ids_for = (%ids_for, read_COG_fasta($infile));
}

Чтобы добавить ключ к га sh, вы создаете список текущих пар ключ-значение, добавляете новую пару, а затем присваиваете ей все обратно: ha sh.

Что произойдет, если вы берете результаты из 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 %hash; # v5.26 feature!
    }

Вы можете сделать то же самое вещи с ключами, которые вы получите обратно, чтобы вы могли отслеживать размер.

...