在 perl 中实例化函数中的哈希是低效的吗?

Is instantiating a hash in a function inefficient in perl?

做下面这些,效率,坏习惯...有什么区别吗?

(在更大哈希值的上下文中并通过许多函数发送它们)

sub function {
  my ($self, $hash_ref) = @_;
  my %hash = %{$hash_ref};
  print $hash{$key};
  return;
}

相比于:

sub function {
  my ($self, $hash_ref) = @_;
  print $hash_ref->{$key};
  return;
}

第一个片段很愚蠢。但是模拟命名参数是convenient practice

sub function {
   my ($self, %params ) = @_;
   ...
} 

因此,通过引用传递 arrays/hashes,创建新的(特别是大的)散列会慢得多。但是 "named arguments" hack 没有什么不好的。

您现在是否存在 key/value 切片(仅限 v5.20+)?您可以通过这种方式轻松复制部分哈希: 我的 %foo =(一 => 1,二 => 2,三 => 3,四 => 4); 我的 %bar = %foo{'one', 'four'};

更多信息见perldoc perldata

假设 %$hash_ref 包含 N 个元素。

除了第二个代码段之外,第一个代码段还执行以下操作:

  • 创建 N 个标量。 (每个都可以涉及多个内存分配。)
  • 向堆栈添加 N*2 个标量。 (便宜。)
  • 创建哈希。 (更多内存分配...)
  • 向散列中添加 N 个元素。 (更多内存分配...)

除了第一个代码段之外,第二个代码段还执行以下操作:

  • [没什么。它是第一个片段的完整子集]

因此,第一个片段的效率远低于第二个片段。由于具有额外的代码,它也更加复杂。完全没有好处和大量的成本决定了应该避免第一个片段中使用的模式。

sub 的第一个版本创建了数据结构的本地副本,引用传递给它。当然,它的效率要低得多。

这样做有一个正当理由:确保调用方中的数据未更改。 local %hash 可以根据需要或方便在 sub 中更改,调用代码中的数据不受影响。这样,调用者中的数据也可以防止意外更改。

完成数据本地副本的另一个原因,尤其是对于更深层次的数据结构,是为了避免长链的取消引用,从而简化代码;因此可以复制部分深层层次结构以实现更简单的访问。那么这仅仅是为了(假定的)编程方便。

所以在所示示例中,绝对没有理由制作本地副本。但是,大概问题是关于潜艇的,那里有更多的工作要做,然后什么是最好的取决于细节。