在Perl中深度复制哈希散列的最佳方法是什么?

Oes*_*sor 24 perl deep-copy

可能重复:
在Perl中制作数据结构的深层副本的最佳方法是什么?

在我开始自己编写代码并重新发明轮子之前,如何在不复制hashref的情况下复制散列哈希?

我正在通过Config :: General读取散列哈希值.即,数据结构是:

my %config = ( group => { item1 => { foo => 'value',
                                     bar => 'value',
                                   },
                          item2 => { foo => 'value',
                                     bar => 'value',
                                   },
                          item3 => { foo => 'value',
                                     bar => 'value',
                                   },
                        },
             );
Run Code Online (Sandbox Code Playgroud)

然后我通过解除引用来从配置中取出我的组,并在重写配置文件之前在运行时更改内容:

my %group = %{$config{'group'}};
Run Code Online (Sandbox Code Playgroud)

问题是我需要检查是否进行了更改并对系统的文件结构进行了相关更改.我不能通过检查来做到这一点:

if ($group{'item1'}{'foo'} ne $config{'group'}{'item1'}{'foo'}) {
    ### Stuff!
}
Run Code Online (Sandbox Code Playgroud)

as $group{'item1'}$config{'group'}{'item1'}都是完全相同的hashref.

现在虽然简单地重新解析配置文件并在保存到磁盘之前将磁盘中已解析的副本与编辑后的版本进行比较应该是微不足道的,但我确信有一种方法可以对复杂数据结构进行嵌套解引用,复制哈希引用的内容,而不是简单地复制引用本身.对CPAN的粗略检查并没有改变任何事情.我错过了什么?

基准

得到了我的答案:

#!/usr/bin/perl

use Benchmark qw(:all) ;
use Storable qw(dclone);
use Clone qw(clone);

my %config = ( group => { item1 => { foo => 'value',
                                     bar => 'value',
                                   },
                          item2 => { foo => 'value',
                                     bar => 'value',
                                   },
                          item3 => { foo => 'value',
                                     bar => 'value',
                                   },
                        },
             );

my $ref = $config{'group'};

timethese(100000, {
  'Clone' => sub { my %group = %{ clone $ref }},
  'Storable' => sub {  my %group = %{ dclone $ref }},
});
Run Code Online (Sandbox Code Playgroud)

结果是:

Benchmark: timing 100000 iterations of Clone, Storable...
   Clone:  2 wallclock secs ( 2.26 usr +  0.01 sys =  2.27 CPU) @ 44052.86/s (n=100000)
Storable:  5 wallclock secs ( 4.71 usr +  0.02 sys =  4.73 CPU) @ 21141.65/s (n=100000)

cod*_*ead 36

use Storable qw(dclone);
$group2 = dclone(\%group);
Run Code Online (Sandbox Code Playgroud)


Oes*_*sor 30

从Storable :: dclone文档中我发现了Clone:

my $copy = clone (\@array);

# or

my %copy = %{ clone (\%hash) };
Run Code Online (Sandbox Code Playgroud)

不需要灵活性,声称比Storable :: dclone更快.

  • 基准测试显示这大约是dclone的两倍 (2认同)

Eth*_*her 7

深度数据结构101:

  • 使用可存储dclone制作结构的深层副本,并freezethaw序列化/反序列化他们的存储(比如在数据库中,或者一个HTTP cookie(但你应该加密,任何你发送给用户,以使其难以篡改).
  • 使用Data :: Compare(或单元测试中的Test :: DeepTest :: Differences)来比较两个深层数据结构.
  • 在调试中使用Data :: DumperData :: Dump来查看对象的外观.但是,不要将其用作篡改另一个对象内部的许可证; 使用API​​.:)