Вы можете установить количество сегментов для хэша следующим образом:
keys(%hash) = 128;
Число будет округлено до степени, равной двум.
При этом очень маловероятночто замедление, которое вы видите, происходит из-за избыточных коллизий хэшей, поскольку Perl будет динамически увеличивать количество сегментов по мере необходимости.А начиная с 5.8.2, он даже обнаружит патологические данные, которые приводят к чрезмерному использованию данного сегмента, и перенастроит функцию хеширования для этого хэша.
Покажите ваш код, и мы, вероятно, сможем помочь найти настоящийпроблема.
Демонстрация большого количества хеш-ключей (не позволяйте этому продолжаться, пока у вас не останется памяти ...):
use strict;
use warnings;
my $start = time();
my %hash;
$SIG{ALRM} = sub {
alarm 1;
printf(
"%.0f keys/s; %d keys, %s buckets used\n",
keys(%hash) / (time() - $start),
scalar(keys(%hash)),
scalar(%hash)
);
};
alarm 1;
$hash{rand()}++ while 1;
Как только появится МНОГОклавиш, вы заметите ощутимое замедление, когда нужно увеличить количество сегментов, но оно все еще остается довольно равномерным.
Глядя на ваш код, чем больше слов загружено, тем больше работы ему придетсясделать для каждого слова.
Вы можете исправить это, изменив это:
my @aWords;
if(defined($hNgramsToWord{$ngram})) {
@aWords = @{$hNgramsToWord{$ngram}};
}
push (@aWords, $word);
$hNgramsToWord{$ngram} = \@aWords;
на следующее:
push @{ $hNgramsToWord{$ngram} }, $word;
Нет необходимости копировать массив дважды.Не нужно проверять, есть ли в ngram запись, она автоматически активирует для вас ссылку на массив.