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]