my $AoH; for my $n_rec (1, 10, 100, 1000) { say ""; say "=== num of records is: ", $n_rec; $AoH = create_data (1, $n_rec); is_deeply ([ sort $_->() ], [ sort &slice_join ]) for \&list_join, \&grep_map, \&map_map; cmpthese ( -1, { map_map => \&map_map, grep_map => \&grep_map, list_join => \&list_join, slice_join => \&slice_join, }); } done_testing; sub list_join { my %H; %H = (%H, %$_) for @$AoH; return keys %H; } # list_join sub slice_join { my %H; @H{keys %$_} = () for @$AoH; return keys %H; } # slice_join sub grep_map { my %seen; return grep { !$seen{$_}++ } map { keys %$_ } @$AoH; } # grep_map sub map_map { my %H = map { $_ => 1 } map { keys %$_ } @$AoH; return keys %H; } # map_map sub create_data { my ($density, $records) = @_; my @AoH; push @AoH, {map { rand 100 <= $density ? ("$_" => $_) : () } "A" .. "ZZ"} for 1 .. $records; return \@AoH; }