arrays - 将大值传递给模块

标签 arrays perl module subroutine

我有一个程序很慢,并试图提高性能。脚本“使用”模块中的一个子,并将一个非常大的数组传递给子。经过一番修改,我意识到如果我将子直接移动到父脚本中,并使数组全局而不是本地(所以我不必传递它),脚本会大大加快(在几分钟内运行它正在占用天)。
我真的很希望能够在模块中包含那个子(因为我有很多脚本调用同一个子)。但我也希望它快点。 :-)
半伪代码
page.pl:

package Page;

use Star;
my @fileBytes=();
open(StarFile, "<$File");
binmode(StarFile);
while (read(StarFile, $FileValues, 1)) {
  push @fileBytes, $FileValues; 
}
close(StarFile);

&parseBlock(\@fileBytes);
模块.pl:
package Star;

sub parseBlock {
  my ($fileBytes) = @_;
  my @fileBytes = @{ $fileBytes };

  ...
}
一些阅读在这里:https://www.perlmonks.org/?node=Variable%20Scoping%20in%20Perl%3A%20the%20basics告诉我我想处理范围。所以如果我用“我们的”而不是“我的”来定义@fileBytes,它就会变成一个包值。据我所知,这通常在模块文件中。但我从 parent 的值(value)开始。
所以我可以让 parent 也成为一个包,定义:
我们的@fileBytes
然后从模块中引用它,至少类似于:
@Page::fileBytes
我想我至少在理论上是正确的。
当我想从不同的脚本中使用 sub 时,我的问题出现了:
其他.pl:
package Other;
use Star;

  my @fileBytes=();
  open(StarFile, "<$File");
  binmode(StarFile);
  while (read(StarFile, $FileValues, 1)) {
    push @fileBytes, $FileValues; 
  }
  close(StarFile);

&parseBlock(\@fileBytes, $offset);
现在我传递的值是 @Other::fileBytes 。我使用图书馆的次数越多,这个问题就越严重。
我想做的是在模块中有子例程,但不必传递(我相信这是创建一个新值,这一定很慢)@fileBytes 数据,因为它是“全局的”,在这样的一种我可以使用集中式子的方法。

最佳答案

您不能将数组传递给 subs,只能传递标量。当一个人使用 f(@a) ,一个是传递数组的元素。这不会创建任何新的标量或复制任何标量,因此它实际上仍然非常快。
但是,即使是那么小的成本也可以避免。这是通过传递对数组的引用来完成的:f(\@a) .这确实创建了一个标量,但它是所有标量中最轻的。
这就是你已经在做的事情,所以从调用 sub 的角度来看,你已经是最快的了。您面临的问题是您在调用 sub 后立即执行的操作的结果:您创建一个新数组并将提供的数组的每个元素复制到这个新数组中。

my @fileBytes = @{ $fileBytes };  # Copies every element.
删除该行,您的问题就解决了。当然,您需要将使用重复数组 ( @fileBytes ) 的任何代码更改为使用原始数组 ( @$fileBytes )。唯一需要注意的是,对数组的任何更改都将反射(reflect)在通过引用传递给子的数组中,因为它是同一个数组。

替代解决方案
如果您坚持避免使用引用,则可以使用以下内容:
use experimental qw( declared_refs );

my \@fileBytes = $fileBytes;
有效地使@fileBytes @$fileBytes 的别名.不涉及复制。它不是免费的,但也不昂贵(O(1))。就像修改 @$filesBytes直接修改@fileBytes将影响调用者中的数组。
一般来说,应该避免在生产环境中使用实验性代码,但开发人员计划在 Perl 的下一个主要版本中默认启用它,因此他们肯定认为它相当稳定。

关于arrays - 将大值传递给模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64720394/

相关文章:

c - Google.com 是如何创建的?

module - 隐藏在 OCaml 中的外部和内部接口(interface)和信息

PHP SimpleXML 到 JSON 编码单元素数组

javascript - 使用索引合并两个数组

json - Perl将数据转换为JSON格式

linux - 从 URL 批量下载

python - 不同形状数组的Numpy距离计算

c# - 将 JSON 数组值合并到单个 CSV 列中

javascript - 如何将旧版 JS 应用程序迁移到模块

module - 当有 main.rs 和 lib.rs 时 Rust 模块混淆