gpt4 book ai didi

arrays - perl 中的类 C 数组

转载 作者:行者123 更新时间:2023-12-04 04:53:46 25 4
gpt4 key购买 nike

我想在内存中创建和操作大型(4 字节)整数数组。大体上,我的意思是大约数亿。阵列中的每个单元格将充当染色体上位置的计数器。我所需要的只是让它适合内存,并且可以快速(O(1))访问元素。我计算的东西不是稀疏特征,所以我不能使用稀疏数组。

我不能用常规的 perl 列表来做到这一点,因为 perl(至少在我的机器上)每个元素使用 64 个字节,所以我使用的大多数生物的基因组都太大了。我尝试通过 SQLite 和哈希绑定(bind)将数据存储在磁盘上,尽管它们可以工作,但速度非常慢,尤其是在普通驱动器上。 (当我在 4 驱动器 raid 0 上运行时,它工作得相当好)。

我以为我可以使用 PDL 数组,b/c 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() 性能,或者知道可以实现此目的的不同模块?

最佳答案

我不知道你会得到什么样的性能,但我建议使用 vec功能,记录 here , 将字符串拆分为位字段。我进行了实验,发现我的 Perl 可以容忍高达 500_000_000 的字符串。长字符。这对应于 125,000,000 个 32 位值。

my $data = "\0" x 500_000_000;
vec($data, 0, 32)++; # Increment data[0]
vec($data, 100_000_000, 32)++; # Increment data[100_000_000]

如果这还不够,那么 Perl 的构建中可能有一些东西可以控制限制。或者,如果您认为您可以获得更小的字段 - 例如 16 位计数 - vec将接受 2 到 32 的任何幂的字段宽度。

编辑:我相信字符串大小限制与 32 位 Windows 进程上的 2GB 最大私有(private)工作集有关。如果您正在运行 Linux 或拥有 64 位 perl,您可能比我幸运。

我已经像这样添加到您的基准程序中
my $vec = "\0" x ($N * 4);

cmpthese(-3,{
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);
},
vec => sub {
vec($vec, int(rand($N)), 32)++;
},
});

给出这些结果
          Rate  pdl  vec perl
pdl 472429/s -- -76% -85%
vec 1993101/s 322% -- -37%
perl 3157570/s 568% 58% --

所以使用 vec是 native 阵列速度的三分之二。想必这是可以接受的。

关于arrays - perl 中的类 C 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9730678/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com