C:\test>228543
Benchmark:
running
CloneCopy, DeepCopy, StorableCopy
, each for at least 1 CPU seconds
...
CloneCopy: 1 wallclock secs ( 1.10 usr + 0.01 sys = 1.11 CPU) @ 27625.00/s (n=30719)
DeepCopy: 1 wallclock secs ( 1.10 usr + 0.00 sys = 1.10 CPU) @ 20539.93/s (n=22635)
StorableCopy: 1 wallclock secs ( 1.03 usr + 0.00 sys = 1.03 CPU) @ 541.67/s (n=559)
Rate StorableCopy DeepCopy CloneCopy
StorableCopy 542/s -- -97% -98%
DeepCopy 20540/s 3692% -- -26%
CloneCopy 27625/s 5000% 34% --
Difference found!
####
$DeepCopy = { $CloneCopy = { $StorableCopy = {
'rrs1' => [ 'rrs1' => [ 'rrs1' => [
\\1, \\1, \\1,
\\2, \\2, \\2,
\\3, \\3, \\3,
\\4, \\4, \\4,
\\5 \\5 \\5
], ], ],
'rrs2' => [ 'rrs2' => [ 'rrs2' => [
$VAR1->{'rrs1'}[0], $VAR2->{'rrs1'}[0], $VAR3->{'rrs1'}[0],
$VAR1->{'rrs1'}[1], $VAR2->{'rrs1'}[1], $VAR3->{'rrs1'}[1],
$VAR1->{'rrs1'}[2], $VAR2->{'rrs1'}[2], $VAR3->{'rrs1'}[2],
$VAR1->{'rrs1'}[3], $VAR2->{'rrs1'}[3], $VAR3->{'rrs1'}[3],
$VAR1->{'rrs1'}[4] $VAR2->{'rrs1'}[4] $VAR3->{'rrs1'}[4]
], ], ],
'h1' => { 'h1' => { 'h1' => {
'A' => 1, 'A' => 1, 'A' => 1,
'B' => 2, 'B' => 2, 'B' => 2,
'C' => 3, 'C' => 3, 'C' => 3,
'D' => 4, 'D' => 4, 'D' => 4,
'E' => 5 'E' => 5 'E' => 5
}, }, },
'rs' => [ 'rs' => [ 'rs' => [
${$VAR1->{'rrs1'}[0]}, ${$VAR2->{'rrs1'}[0]}, ${$VAR3->{'rrs1'}[0]},
${$VAR1->{'rrs1'}[1]}, ${$VAR2->{'rrs1'}[1]}, ${$VAR3->{'rrs1'}[1]},
${$VAR1->{'rrs1'}[2]}, ${$VAR2->{'rrs1'}[2]}, ${$VAR3->{'rrs1'}[2]},
${$VAR1->{'rrs1'}[3]}, ${$VAR2->{'rrs1'}[3]}, ${$VAR3->{'rrs1'}[3]},
${$VAR1->{'rrs1'}[4]} ${$VAR2->{'rrs1'}[4]} ${$VAR3->{'rrs1'}[4]}
], ], ],
'self' => [ 'self' => $VAR2->{'rs'} 'self' => $VAR3->{'rs'}
${$VAR1->{'rrs1'}[0]} };, };
${$VAR1->{'rrs1'}[1]},
${$VAR1->{'rrs1'}[2]},
${$VAR1->{'rrs1'}[3]},
${$VAR1->{'rrs1'}[4]}
]
};
####
#! perl -slw
use strict;
use Clone qw[clone];
use Data::Dumper;
use Storable qw[dclone freeze];
use Benchmark qw[cmpthese];
sub deepcopy{
return $_[0] unless ref $_[0];
return [ map{ deepcopy($_) } @{$_[0]} ] if ref $_[0] eq 'ARRAY';
return { map{ deepcopy($_) } %{$_[0]} } if ref $_[0] eq 'HASH';
return \do{ ${$_[0]} };
}
sub factorial { my ($f,$n) = (1,shift); $f *= $n-- while( $n ); $f; }
sub multicheck {
my $check = factorial($#_);
my ($i, @ok) = (0, (0) x @_);
while (@_) {
my $first = shift;
for my $next (@_) {
$ok[$i] += ($first eq $next);
}
$i++;
}
my $count = do{ local $a; $a += $_ for @ok; $a; };
return $count == $check;
}
my @rs = \do{1..5};
my @rrs1 = \(@rs);
my @rrs2 = \(@rs);
my %h1 = do{ my $key='A'; map{ $key++ => $_} 1..5; };
my %hash = ( rs=> \@rs, rrs1=> \@rrs1, rrs2=> \@rrs2, h1=>\%h1 );
$hash{self} = $hash{rs};
my $DeepCopy = deepcopy( \%hash );
my $CloneCopy = clone( \%hash );
my $StorableCopy= dclone( \%hash );
#print Dumper [\%hash, $CloneCopy, $StorableCopy, $DeepCopy];
=pod Comment (moan)
The following code should, according to my reading of the Data::Dumper pod, result in
$DDumperCopy becoming a ref to a copy of %hash,, but it doesn't? :(
my $DDumperCopy;
$Data::Dumper::Purity = 1;
$DDumperCopy = eval( Dumper(\%hash) ) and warn $@ if $@;
print Dumper $DDumperCopy;
=cut
cmpthese( -1, {
DeepCopy => '$DeepCopy = deepcopy( \%hash );',
CloneCopy => '$CloneCopy = clone( \$hash );',
StorableCopy=> '$StorableCopy = dclone( \%hash );',
# DDumperCopy => '',
});
my $strDeepCopy = freeze( $DeepCopy );
my $strCloneCopy = freeze( $CloneCopy );
my $strStorableCopy = freeze( $StorableCopy );
print "\nDifferences found!"
unless multicheck( $strDeepCopy, $strCloneCopy, $strStorableCopy );
#print Dumper $DeepCopy, $CloneCopy, $StorableCopy
# unless multicheck( $strDeepCopy, $strCloneCopy, $strStorableCopy );