在perl脚本中释放内存

在perl脚本中释放内存

我想要所有这些组合,但我没有足够的内存。如何释放脚本中的内存?

use strict;
use warnings;

use Algorithm::Combinatorics 'variations_with_repetition';

my @let = qw/ A G C T /;
my @cad = variations_with_repetition(\@let, 24);
print "@$_\n" for @cad;

答案1

解决方案是简单地使用iterators.通过将结果分配variations_with_repetition给标量,它会生成一个迭代器,您每次都可以询问该迭代器以获取下一个元素。通过这样做,您不必将整个列表保留在内存中,并且可以立即访问第一个元素。这是一个可爱的概念,叫做惰性求值。这是您的案例的代码:

use strict;
use warnings;
use Algorithm::Combinatorics 'variations_with_repetition';

my @let = qw / A G C T/;
my $cad = variations_with_repetition(\@let,24);
while(my $c = $cad->next)
{
    print "@$c\n";
}

请注意,迭代器实际上返回对数组的引用,您必须首先取消引用该数组,然后加入或对其执行任何您喜欢的操作。

测试结果:我无法在我的机器上运行初始代码(内存使用量按预期无限增长),但是使用迭代器,我立即开始获取输出行,而 perl 几乎不消耗任何内存。

答案2

嗯,枚举字母表上的单词(A、G、C、T)与以四为基数进行计数非常相似。知道这一点(删除对 head 的调用;它只是在测试时截断很长的输出):

{ echo 4o; seq 0 $((4 ** 24 - 1)) | sed 's/$/p/'; } | dc | awk '{ printf "%024d\n", $1 }' | tr 0-4 AGCT | head

解释:

  • echo 4o是一个命令,指示dc以四进制输出;

  • seq要求对 24 位四进制数字涵盖的整个范围进行计数;

  • sed在每行附加一个p,要求dc打印每个数字(记住以四为基数);

  • awk前置足够的零以使数字打印 24 位;

  • tr将数字 (0, 1, 2, 3) 转换为字母表 (A, G, C, T)。

相关内容