我有一大堆哈希值,大约0.5Gb,存储在内存中,我需要从中删除一些元素,大约10%遍布整个数组。
什么更有可能做得最好,做一个grep,或者确定需要删除的元素,并将它们拼接出去?
谢谢,
西蒙
答案 0 :(得分:5)
基准吗?我猜,不知道你的数据是什么样的,grep会比多次调用具有大量元素的数组更快。
答案 1 :(得分:2)
如果您知道要保持的元素,那么您只需使用数组切片对其进行索引:
@want = @all[ @wanted ];
或
@all = @all[ @wanted ];
至于grep
和splice中的哪一个是最快的,splice
将是最快的,因为它需要做的就是在C中移动一些指针,并删除你不再从内存中保留的东西,grep
需要更多的工作,因为它需要为原始列表的每个成员调用您的选择函数。
答案 2 :(得分:0)
如果你已经知道你有兴趣删除哪些元素,那么它将更快地定义,因为你不必搜索它们,只删除它们。否则,grep
是您快速过滤方法的最佳选择。
答案 3 :(得分:0)
splice
可能会在您描述的条件下转到O(n ^ 2)(因为它会移动数组内容),而grep
/ slice会分配O(n)额外内存(可能很多)小于500GB,但仍然......)。
虽然有一个没有额外内存的线性解决方案,但看起来更像C,而不像Perl:
sub inplace_grep {
my ($code, $array) = @_;
# move elements backwards
for (my ($to, $from)=(0,0); $from < @$array; $from++) {
$code->($array->[$from]) or next;
$array->[$to++] = $array->[$from];
};
# remove tail
splice @$array, $to;
};
关于grep内存使用的 更新: - 您可以通过使用大量数据并查找brk
系统调用来快速测试额外的内存分配。在我的系统(linux,perl 5.10)上它确实如此。
strace -e trace=brk perl -MTime::HiRes -wle \
'print "start ".time; my @array = 1..10**7; print "alloc ".time;
@array = grep { $_ %2 } @array; print "grep ".time'