Perl中有真正的向量(一维数组)吗?

时间:2018-01-22 11:50:05

标签: c performance perl vector malloc

我知道Perl中的传统“列表”在内部完全实现为真正的双链表。因此对列表元素的索引访问很慢。这是列表的动态性质的成本,可以切片,扩展,缩小。

但是出于性能原因,有可能使malloc()一些内存块并创建静态大小的矢量和其元素的预定义大小是非常好的:例如,固定大小的双链表可能表示为大小为4(prev_v_index)+4(next_v_index)+8(data_ptr aka REF)= 16字节的元素序列。所以我们可以访问这个向量的每个元素,因为我们通常用C语言编译语言:elem_ptr = vector_ptr +(index * elem_size) - 对于某些特定于architecure的对齐(x86_64为8个字节),对元素的访问速度非常快。 / p>

也许已经有一些XS模块用于在Perl5中使用固定向量进行操作了吗?

2 个答案:

答案 0 :(得分:4)

Perl的数组(@array变量或[...]引用)确实使用了连续的内存区域。它们不是链表。但是,这些数组只保存指向标量值的指针,而不是值本身。这是Perl数据模型的必要限制。

如果您了解C ++,Perl数组可以被认为类似于std::vector<Scalar*>,除了Perl的数组可以在前后推送和弹出。

要调整Perl数组的大小,可以指定最后一个索引。例如。预先分配50个元素:

my @array;
$#array = 50 - 1;

如果你需要Perl中的紧凑数据存储,那么你将不得不使用字符串。给定固定大小的记录,您可以使用substrpack / unpack来获取和设置一条记录来自Perl数据结构的数据。

答案 1 :(得分:2)

您可以使用vec函数将字符串用作向量。例如,您可以将布尔值打包到单个位中。

  

vec EXPR,OFFSET,BITS

     

将EXPR中的字符串视为由元素组成的位向量   width BITS并返回由指定的元素的值   OFFSET作为无符号整数。 BITS因此指定了   为该位中的每个元素保留的位数   向量。这必须是1到32的幂(或64,如果你的   平台支持)。

那就是说,你对阵列访问“缓慢”的担忧是没有根据的,你对perl内部的信念是不正确的。阵列性能可能足够快。在您分析代码并证明其成为瓶颈之前,不要试图对其进行“优化”。