Perl:将大字符串列表传输到子例程而不进行复制

发布于 2024-12-28 14:24:21 字数 611 浏览 5 评论 0原文

任务是将巨大字符串列表传输到子例程,但避免在传输时复制它们。假设我有一个名为 $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 模块中的方法。

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

The task is to transfer a list of huge strings to subroutibe, but avoiding their copying on transfer. Say I have a reference named $ref pointing to the very large string. Also let's have f($) subroutine accepting a single argument. There are no problem to transfer this string to f:

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

Really I have not a single string, but list of them, let's assign them to @a:

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

Now the problem would be solved by

f(map {$_} @a);

but map does copy every dereferenced item from @a, and then transfer those copied instances to f.

I have no control on f since it actually is the method from CPAN module.

So is there possible to solve the task?
Much thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鲜肉鲜肉永远不皱 2025-01-04 14:24:21

是的,“地图”总是复制的方式可能有点烦人。

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

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

use Data::Alias qw( alias deref );

f(deref @a);

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

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

比如说,您的数据一次会产生一个(巨大的)值,并且您希望将这些值放入一个数组中。虽然您目前可能会这样做,但

push @a, \$value;

您可以将其更改为

alias push @a, $value;

如果您有两个列表(包含大量元素)想要将其放入一个大数组中,则可以这样做

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

Yes, 'map' can be a bit annoying in the way it always copies.

You can dereference a all elements from entire list into an array, without copying, using Data::Alias::deref.

Assuming @a is an array of references, and you want to call a function f() with an argument list which is the result of dereferencing those references, then you can do

use Data::Alias qw( alias deref );

f(deref @a);

(Note that Data::Alias exists as a distro module for (for example) Ubuntu (libdata-alias-perl), so you should be able to use it even if you can't use CPAN directly.)

In fact, if you're dealing with a lot of large string objects and minimising copying is a concern, you might want to use Data::Alias more extensively. In fact, once you have Data::Alias in your programming arsenal, you might find you don't need to store the data in your array as references at all.

Say, your data comes to you one (huge) value at a time, and you want to put those values into an array. Whereas you might currently do

push @a, \$value;

you could change that to

alias push @a, $value;

If you have two lists (of huge elements) that you want to make into one big array, you can do this

alias my @one_big_array = (@a, @b);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文