C-подобные массивы в Perl

Я хочу создавать и манипулировать большими массивами (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(), или знает другой модуль, который может это сделать?

8
задан user1481 16 March 2012 в 01:35
поделиться