给出以下代码,$z
引用的散列是否会或多或少地消耗与( %$x, %$y)
使用的相同的内存?
如果是这样,是否有一种方法可以使用单个引用从$x
或$y
像$z->{$somekeytoXorY}
引用的哈希中调用数据,而不会影响性能和内存?
use strict;
use warnings;
my $x = {
1 => 'a',
2 => 'b',
};
my $y = {
3 => 'c',
4 => 'd',
};
my $z = {
%$x, %$y
};
散列引用实际上指向使用tie
和DB_File
创建的大型散列。
我想知道是否有可能仅对它们使用单个哈希,这样我就不需要将所有内容都转储到内存中。另外,我可能一次使用其中两个以上。
答案 0 :(得分:3)
绑定的哈希根本不是哈希。它们是子例程的接口。由于它们是代码,而不是数据,因此一般而言,谈论绑定哈希的内存和性能毫无意义。
让我们先谈谈普通哈希。
ALB
会将$z = { %$x, %$y };
和%$x
的标量复制到%$y
中,所以是的,它将占用两倍的内存(假设没有重复的键)。
您可以共享标量:
%$z
您仍然会使用与两个哈希中的元素数量成比例的内存,但是如果use Data::Alias qw( alias );
my $z = {};
alias $z->{$_} = $x->{$_} for keys(%$x);
alias $z->{$_} = $y->{$_} for keys(%$y);
和%$x
实际上是哈希,则它会比以前少得多。这可能不会为绑定哈希节省任何内存。
另一种选择是根本不合并数据。您可以自己使用绑定哈希...
%$y
...但是没有理由使代码看起来像哈希。您可以只使用一个对象。
package Tie::MergedHashes;
use Carp qw( croak );
sub new { my $pkg = shift; $pkg->TIEHASH(@_); }
sub TIEHASH { bless [ @_ ], $_[0] }
sub STORE { croak("Not allowed"); }
sub FETCH { for (@{$_[0]}) { return $_->{$_[1]} if exists($_->{$_[1]}); } return undef; }
...
my $z = {};
tie %$z, MergedHashes => ($y, $x);
$z->{$key}
答案 1 :(得分:0)
简单的答案是肯定的。
如果要从两个哈希引用中获取所有键而不创建新的哈希引用,并且假设没有重复的键,则可以执行类似的操作。
use List::Util qw( uniq );
my @keys = uniq( keys( %$x ), keys( %$y ) );
然后从类似的任何一个数组中获取值
my $value = exists $y->{$key} ? $y->{$key} : $x->{$key};
顺便问一句,为什么要使用哈希引用而不是哈希,为什么要考虑内存以致您需要问这个问题?