在perl中,在函数中实例化哈希是否效率低下?

在perl中,在函数中实例化哈希是否效率低下?,perl,hash,reference,subroutine,Perl,Hash,Reference,Subroutine,做以下事情有什么区别吗,效率,坏习惯 (在更大的散列并通过许多函数发送它们的上下文中) 与之相比: sub function { my ($self, $hash_ref) = @_; print $hash_ref->{$key}; return; } 第一个片段很傻。但这是为了模拟命名参数: sub function { my ($self, %params ) = @_; ... } 因此,通过引用传递数组/散列,创建新的(特别是大的)散列将慢得多。但“

做以下事情有什么区别吗,效率,坏习惯

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

与之相比:

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

第一个片段很傻。但这是为了模拟命名参数:

sub function {
   my ($self, %params ) = @_;
   ...
} 
因此,通过引用传递数组/散列,创建新的(特别是大的)散列将慢得多。但“命名参数”黑客并没有什么坏处

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


第一个代码片段中的更多信息是愚蠢的。但这是为了模拟命名参数:

sub function {
   my ($self, %params ) = @_;
   ...
} 
因此,通过引用传递数组/散列,创建新的(特别是大的)散列将慢得多。但“命名参数”黑客并没有什么坏处

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


perldoc perldata

中的更多信息,假设
%$hash\u ref
包含N个元素

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

  • 创建N个标量。(每个内存分配可能涉及多个内存分配。)
  • 将N*2个标量添加到堆栈中。(便宜。)
  • 创建哈希。(更多内存分配…)
  • 将N个元素添加到哈希中。(更多内存分配…)
除了第一个代码段的功能外,第二个代码段还执行以下操作:

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

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

假设
%$hash\u ref
包含N个元素

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

  • 创建N个标量。(每个内存分配可能涉及多个内存分配。)
  • 将N*2个标量添加到堆栈中。(便宜。)
  • 创建哈希。(更多内存分配…)
  • 将N个元素添加到哈希中。(更多内存分配…)
除了第一个代码段的功能外,第二个代码段还执行以下操作:

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

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

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

这样做有一个合理的原因:确保调用方中的数据没有更改。本地
%hash
可以根据需要或方便地在sub中更改,并且调用代码中的数据不受影响。这样,调用者中的数据也可以防止意外更改

进行数据本地拷贝的另一个原因,特别是使用更深层的数据结构,是为了避免长链的解引用,从而简化代码;因此,可以复制深层层次结构的一部分以简化访问。那么这仅仅是为了(假定的)编程方便


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

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

这样做有一个合理的原因:确保调用方中的数据没有更改。本地
%hash
可以根据需要或方便地在sub中更改,并且调用代码中的数据不受影响。这样,调用者中的数据也可以防止意外更改

进行数据本地拷贝的另一个原因,特别是使用更深层的数据结构,是为了避免长链的解引用,从而简化代码;因此,可以复制深层层次结构的一部分以简化访问。那么这仅仅是为了(假定的)编程方便


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

第一个sub无理由地复制哈希。第一个sub无理由地复制哈希。第一个片段中的模式的一个小好处是:不能意外地激活
%$hash\u ref
的元素。但这在实践中从未发生过,所以这是一个毫无价值的好处。我不会说“从未发生”。在处理多层结构时,这种情况经常发生。但更重要的是,我只会在明确表示不想修改原始哈希值的情况下使用第一个方法。@Grinnz,好吧,我从未见过这种情况发生。我甚至不确定我是否听说过这件事。这主要是因为
f($h{$k})
特别防止了自活的发生,即使
$h{$k}
被评估为左值。只有($h{$k}{}的
会这样做,谁会这样做?@Grinnz,也许你在考虑引用的自动激活<代码>无自生
是一种更好的保护方法。第一个代码片段中的模式有一个小小的好处:不能意外地激活
%$hash\u ref
的元素。但这在实践中从未发生过,所以这是一个毫无价值的好处。我不会说“从未发生”。在处理多层次问题时,这种情况经常发生