Я хочу создавать и манипулировать большими массивами (4-байтовых) целых чисел в памяти. Под большими я подразумеваю порядка сотен миллионов. Каждая ячейка в массиве будет действовать как счетчик положения на хромосоме. Все, что мне нужно, это чтобы он поместился в памяти и имел быстрый (O(1)) доступ к элементам. То, что я считаю, не является разреженной функцией, поэтому я не могу использовать разреженный массив.
Я не могу сделать это с помощью обычного списка Perl, потому что Perl (по крайней мере, на моей машине) использует 64 байта на элемент, поэтому геномы большинства организмов, с которыми я работаю, слишком велики. Я пытался хранить данные на диске с помощью SQLite и связывания хэшей, и хотя они работают, они очень медленные, особенно на обычных дисках. (Это работает достаточно хорошо, когда я запускаю рейд 0 с 4 дисками).
Я думал, что смогу использовать массивы PDL, потому что PDL хранит свои массивы так же, как это делает C, используя только 4 байта на элемент. Однако я обнаружил, что скорость обновления мучительно медленная по сравнению со списками perl:
use PDL;
use Benchmark qw/cmpthese/;
my $N = 1_000_000;
my @perl = (0 .. $N - 1);
my $pdl = zeroes $N;
cmpthese(-1,{
perl => sub{
$perl[int(rand($N))]++;
},
pdl => sub{
# note that I'm not even incrementing here just setting to 1
$pdl->set(int(rand($N)), 1);
}
});
Возвраты:
Rate pdl perl
pdl 481208/s -- -87%
perl 3640889/s 657% --
Кто-нибудь знает, как увеличить производительность pdl set(), или знает другой модуль, который может это сделать?