Perl:将大型字符串列表转移到子程序而不进行复制

时间:2012-01-23 13:03:09

标签: perl map reference arguments subroutine

任务是将巨大的字符串列表传输到subroutibe,但避免在传输时复制它们。假设我有一个名为$ref的引用指向非常大的字符串。让我们让f($)子例程接受一个参数。将此字符串传输到f

没有问题
f($$ref); # data pointed by $ref is not copied to temporary value here

我真的没有一个字符串,但列出了它们,让我们将它们分配给@a

my @a = ($ref_1, $ref_2, $ref_3, ...);

现在问题将由

解决
f(map {$$_} @a);

map 复制@a中的每个解除引用的项目,然后将这些复制的实例转移到f

我对f无法控制,因为它实际上是来自CPAN模块的方法。

那么有可能解决这个任务吗? 非常感谢提前。

1 个答案:

答案 0 :(得分:3)

是的,'map'在它总是复制的方式上会有点烦人。

您可以使用Data::Alias::deref将整个列表中的所有元素取消引用到数组中,而无需复制。

假设@a是一个引用数组,并且您希望使用参数列表调用函数f(),该参数列表是取消引用这些引用的结果,那么您可以

use Data::Alias qw( alias deref );

f(deref @a);

(请注意Data::Alias作为(例如)Ubuntu(libdata-alias-perl)的发行版模块存在,因此即使您不能直接使用CPAN,也应该可以使用它。)< / p>

事实上,如果您正在处理大量的字符串对象并且最小化复制是一个问题,那么您可能希望更广泛地使用Data :: Alias。事实上,一旦在编程库中有Data :: Alias,您可能会发现根本不需要将数据存储在数组中。

比如说,您的数据一次只能获得一个(巨大的)值,并且您希望将这些值放入数组中。而您目前可能会这样做

push @a, \$value;

您可以将其更改为

alias push @a, $value;

如果你有两个(巨大的元素)列表,你想做成一个大数组,你可以这样做

alias my @one_big_array = (@a, @b);