合并2个或更多的Perl哈希引用是否会或多或少地消耗两倍的内存?

时间:2018-09-03 15:02:14

标签: perl

给出以下代码,$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
};

更新

散列引用实际上指向使用tieDB_File创建的大型散列。

我想知道是否有可能仅对它们使用单​​个哈希,这样我就不需要将所有内容都转储到内存中。另外,我可能一次使用其中两个以上。

2 个答案:

答案 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};

顺便问一句,为什么要使用哈希引用而不是哈希,为什么要考虑内存以致您需要问这个问题?