If speed matters, I benchmarked this once for a project. In most cases using hash slices was significantly faster. Info from my notes below. The results and dataset generator are in the readmore link:
# benchmark four ways to combine hashes: cmpthese (-10,{ forloop => sub { for (keys %$hash2) { $hash1->{$_} = $hash2->{$_} } }, whileach => sub { while (my($key, $val) = each %$hash2) { $hash1->{$key} = $val; } }, slice => sub { @$hash1{keys %$hash2} = values %$hash2; }, merge => sub { my $hash1 = {%$hash1, %$hash2}; }, },'auto');
# generate dataset of random key-val pairs my %hash; my @keys; my $valstr; for (1..60){ $valstr .= ('A'..'Z', 'a'..'z', 0..9)[rand(62)]; } while ((scalar (keys %hash)) < 20000){ my $keylen = 4 + int rand 16; my $vallen = 8 + int rand 32; my $key; for (1..$keylen){ $key .= ('A'..'Z', 'a'..'z', 0..9)[rand(62)]; } my $val = substr($valstr, $keylen-4, $vallen); $hash{$key} = $val; } use Data::Dumper; open (OUT, ">testhash.dat"); print OUT "package hashdata;\n"; print OUT Dumper \%hash; close OUT;
# generate test hashes from dataset # adjust forloops for hash size & overlap my $hash1 = {}; my $hash2 = {}; { require "testhash.dat"; my $hash = $hashdata::VAR1; for ((keys %$hash)[1..10000]){ $hash1->{$_} = $hash->{$_}; } for ((keys %$hash)[9901..10100]){ $hash2->{$_} = $hash->{$_}; } }
hash1: 10000 keys, hash2: 10000 keys duplicates 1000, added 9000 key/values Rate merge slice forloop whileach merge 7.69/s -- -66% -69% -74% slice 22.9/s 198% -- -7% -22% forloop 24.5/s 219% 7% -- -16% whileach 29.3/s 281% 28% 20% -- ==================== hash1: 10000 keys, hash2: 10000 keys duplicates 9000, added 1000 key/values Rate merge slice forloop whileach merge 10.8/s -- -53% -55% -63% slice 22.9/s 111% -- -5% -22% forloop 24.0/s 121% 5% -- -18% whileach 29.3/s 171% 28% 22% -- ==================== hash1: 10000 keys, hash2: 2000 keys duplicates 1000, added 1000 key/values Rate merge slice forloop whileach merge 15.8/s -- -89% -89% -89% slice 140/s 791% -- -2% -5% forloop 143/s 806% 2% -- -3% whileach 147/s 833% 5% 3% -- ==================== hash1: 10000 keys, hash2: 200 keys duplicates 100, added 100 key/values Rate merge whileach forloop slice merge 18.6/s -- -99% -99% -99% whileach 2113/s 11272% -- -18% -42% forloop 2571/s 13740% 22% -- -29% slice 3614/s 19356% 71% 41% -- ==================== hash1 = 1000 keys, hash2 = 1000 keys: duplicates 100, added 900 key/values Rate merge forloop whileach slice merge 66.2/s -- -65% -74% -76% forloop 188/s 184% -- -26% -33% whileach 255/s 285% 36% -- -9% slice 280/s 324% 49% 10% -- ==================== hash1 = 1000 keys, hash2 = 1000 keys: duplicates 900, added 100 key/values Rate merge whileach slice forloop merge 109/s -- -59% -62% -65% whileach 266/s 145% -- -8% -14% slice 287/s 165% 8% -- -7% forloop 311/s 186% 17% 8% -- ==================== hash1 = 1000 keys, hash2 = 200 keys: duplicates 100 added 100 key/values Rate merge forloop whileach slice merge 175/s -- -87% -89% -93% forloop 1369/s 681% -- -12% -49% whileach 1563/s 791% 14% -- -42% slice 2673/s 1424% 95% 71% -- ==================== hash1 = 100 keys, hash2 = 100 keys: duplicates 10, added 90 key/values Rate merge whileach forloop slice merge 976/s -- -33% -54% -65% whileach 1462/s 50% -- -32% -47% forloop 2140/s 119% 46% -- -23% slice 2780/s 185% 90% 30% -- ==================== hash1 = 100 keys, hash2 = 100 keys: duplicates 90, added 10 key/values Rate whileach merge forloop slice whileach 2378/s -- -4% -45% -55% merge 2472/s 4% -- -42% -53% forloop 4297/s 81% 74% -- -18% slice 5247/s 121% 112% 22% -- ==================== hash1 = 100 keys, hash2 = 20 keys: duplicates 10, added 10 key/values Rate merge whileach forloop slice merge 3826/s -- -75% -81% -85% whileach 15116/s 295% -- -26% -39% forloop 20451/s 435% 35% -- -18% slice 24862/s 550% 64% 22% -- ==================== hash1 = 10 keys, hash2 = 10 keys: duplicates 1, added 9 key/values Rate merge whileach forloop slice merge 17047/s -- -43% -54% -64% whileach 30008/s 76% -- -20% -36% forloop 37405/s 119% 25% -- -20% slice 46782/s 174% 56% 25% -- ==================== hash1 = 10 keys, hash2 = 10 keys: duplicates 9, added 1 key/values Rate merge whileach forloop slice merge 23476/s -- -18% -28% -48% whileach 28730/s 22% -- -12% -37% forloop 32528/s 39% 13% -- -28% slice 45435/s 94% 58% 40% -- ==================== hash1 = 10 keys, hash2 = 4 keys: duplicates 2, added 2 key/values Rate merge whileach forloop slice merge 28306/s -- -57% -64% -72% whileach 65928/s 133% -- -17% -35% forloop 79675/s 181% 21% -- -22% slice 101564/s 259% 54% 27% --
Updated:See reply to ikegami below.
In reply to Re: Combining a hash into another
by hangon
in thread Combining a hash into another
by John M. Dlugosz
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |