perl-整数数组使用太多内存?

perl-整数数组使用太多内存?,perl,types,Perl,Types,当我运行以下脚本时: my @arr = [1..5000000]; for($i=0; $i<5000000; $i++) { $arr[$i] = $i; if($i % 1000000 == 0) { print "$i\n"; } } my@arr=[1..5000000]; 对于($i=0;$i,如果您正在处理如此大的数组,您可能需要使用类似的工具箱 (哦,是的,你是对的:它占用了这么多内存,因为

当我运行以下脚本时:

my @arr = [1..5000000];

for($i=0; $i<5000000; $i++) {
        $arr[$i] = $i;
        if($i % 1000000 == 0) {
                print "$i\n";
        }
}
my@arr=[1..5000000];

对于($i=0;$i,如果您正在处理如此大的数组,您可能需要使用类似的工具箱


(哦,是的,你是对的:它占用了这么多内存,因为它是一个Perl标量数组。)

我的答案的完整修订。看看你的代码,我看到了一些奇怪的东西

my @arr = [1..5000000];
在这里,您将匿名数组引用分配给
$arr[0]
。此数组只包含一个值:数组引用。隐藏的匿名数组包含500万个数字

for($i=0; $i<5000000; $i++) {
        $arr[$i] = $i;
        if($i % 1000000 == 0) {
                print "$i\n";
        }
}

这可能会为您节省一些内存。

您可以使用pack:

my $numbers = "";
$numbers .= pack("N", $_) for (1..5000000);

它肯定会占用更少的空间。因此,您可以使用
substr
unpack
获取值。所有Perl值都在内部表示为Perl标量,这比简单的整数消耗更多的内存。即使标量只包含一个整数。即使标量是
undef


正如其他人所建议的,如果你真的想用这种大数组工作,也许会有点值得注意。

< p>在Perl你总是可以使用C或C++。这可能会给你一些困难工作带来的小空间。 只是一个使用C的想法

#!/usr/bin/perl
use Inline C;
use strict;

for(my $i=0; $i<5000000; $i++) {
        set_array_index($i,$i);
        if($i % 1000000 == 0) {
                #print "$i\n";
                print get_array_index($i)."\n";
        }
}

__END__
__C__

int array[5000000];

void set_array_index(int index,int value) {
    array[index]=value;
}

int get_array_index(int index) {

    if (array[index]==NULL)
        return 0;

    return array[index];
}
!/usr/bin/perl
使用内联C;
严格使用;

对于(my$i=0;$i,您可以使用迭代器,而不是这么大的整数列表

迭代器为每个新值支付函数调用的开销,但可以节省内存


如果我没记错的话,range operator不会在最新的perls中建立如此庞大的列表。

或者,隐式地为您处理包,有:


也可能有兴趣。

以下是互动式
pdl2
课程中的几行内容,展示了如何 这可以使用基本的PDL结构来完成:

pdl> $arr = sequence(long, 5000000) + 1;  # create pdl data array (a.k.a. a piddle)

pdl> help vars                            # see, it is only ~19MB
PDL variables in package main::

Name         Type   Dimension       Flow  State          Mem
----------------------------------------------------------------
$arr           Long D [5000000]            P           19.07MB
$Pi          Double D []                   P            0.01KB

pdl> p which( $arr%1000000 == 0 )         # which returns indexes which are true
[999999 1999999 2999999 3999999 4999999]
有关详细信息,请参阅联机 对PDL的用途进行了很好的介绍。 这些都是最好的 PDL使用和发展的信息来源。回复通常为
快速。

[1..5_000\u 000]
无论是否为常数,都会消耗同样多的内存。问题的一部分在于
my@arr=[1..5000000];
是一个错误,不能按照您的意愿执行。如果编写
my@arr=(1..5000000),您可能会看到更少的使用;
。或者干脆
my@arr;
,因为您没有使用初始化时使用的任何值。@hobbs-我只是举了一个最简单的例子。我的真实脚本确实使用了数组。您需要24个字节来存储Perl标量中的整数值,更多的是字符串:我刚刚阅读了Tie::array::PackedC文档,它似乎是一个interesting解决方案可保持较低的内存使用率。
use Tie::Array::PackedC;
# make @arr use $arr_storage for storing packed elements, by default using 'l!' pack format
tie my @arr, 'Tie::Array::PackedC', my $arr_storage;
pdl> $arr = sequence(long, 5000000) + 1;  # create pdl data array (a.k.a. a piddle)

pdl> help vars                            # see, it is only ~19MB
PDL variables in package main::

Name         Type   Dimension       Flow  State          Mem
----------------------------------------------------------------
$arr           Long D [5000000]            P           19.07MB
$Pi          Double D []                   P            0.01KB

pdl> p which( $arr%1000000 == 0 )         # which returns indexes which are true
[999999 1999999 2999999 3999999 4999999]