Связанные хеши вовсе не являются хешами. Это интерфейсы для подпрограмм. Поскольку они представляют собой код, а не данные, говорить о памяти и производительности связанных хешей вообще не имеет смысла.
Давайте сначала поговорим об обычных хешах.
$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}
... но нет причин делать код похожим на хеш. Вы можете просто использовать объект.
package MergedHashes;
use Carp qw( croak );
sub new { bless [ @_ ], $_[0] }
sub fetch { for (@{$_[0]}) { return $_->{$_[1]} if exists($_->{$_[1]}); } return undef; }
...
my $z = MergedHashes->new($y, $x);
$z->fetch($key)