Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: How to Check Hashes for Missing Items when Keys can be Values and vice versa

by thanos1983 (Parson)
on Jul 26, 2017 at 13:52 UTC ( [id://1196103]=note: print w/replies, xml ) Need Help??


in reply to How to Check Hashes for Missing Items when Keys can be Values and vice versa

Hello ozboomer,

This is not a big improvement but just in case you are interested you can replace the foreach loops with while loops. See sample of code bellow:

#!/usr/bin/perl use strict; use warnings; # use Benchmark qw(:all) ; # WindowsOS use Benchmark::Forking qw( timethese cmpthese ); # UnixOS my @preserved = @ARGV; sub while_test { my %data_hash = (); my %output_hash = (); @ARGV = @preserved; # restore original @ARGV while (<>) { # Build list of unique (site +:dsk) items my ($site, $buf) = split(/,/); my @input_item = split(/:/, $buf); while ( defined ( my $input_field = shift @input_item ) ) { # EX: +"VAR8=36!206!207!" my @dsk_list = ($input_field =~ /([0-9]+)!([0-9]+)!$/); # Get + last 2 of 3 items while ( defined ( my $dsk = shift @dsk_list ) ) { # Each dsk i +tem in the input... next if ($dsk == 0); # Skip '0' dsk items my $key = $site . ":" . $dsk; # Build composite key $data_hash{$key}++; # ...and save it } } } my @sort_data_keys = sort keys %data_hash; while ( defined ( my $key = shift (@sort_data_keys) ) ) { # Build +list of dsk -> (multi sites) my ($site, $dsk) = split(/:/, $key); push( @{$output_hash{$dsk} }, $site ); } my @sort_output_hash = sort {$a <=> $b} keys %output_hash; while ( defined ( my $dsk = shift (@sort_output_hash) ) ) { # Show + list of sites for each dsk # printf("Dsk: %d:\n", $dsk); foreach my $site (sort {$a <=> $b} @{$output_hash{$dsk}}) { # printf(" %d\n", $site); } # printf("\n"); } } sub foreach_test { my %data_hash = (); my %output_hash = (); @ARGV = @preserved; # restore original @ARGV while(<>) { # Build list of unique (site: +dsk) items my ($site, $buf) = split(/,/); my @input_item = split(/:/, $buf); foreach my $input_field (@input_item) { # EX: "VAR8=36!206!207! +" my @dsk_list = ($input_field =~ /([0-9]+)!([0-9]+)!$/); # Get + last 2 of 3 items foreach my $dsk (@dsk_list) { # Each dsk item in the + input... next if ($dsk == 0); # Skip '0' dsk items my $key = $site . ":" . $dsk; # Build composite key $data_hash{$key}++; # ...and save it } } } foreach my $key ( sort keys %data_hash ) { # Build list of dsk +-> (multi sites) my ($site, $dsk) = split(/:/, $key); push( @{$output_hash{$dsk} }, $site ); } foreach my $dsk (sort {$a <=> $b} keys %output_hash) { # Show lis +t of sites for each dsk # printf("Dsk: %d:\n", $dsk); foreach my $site (sort {$a <=> $b} @{$output_hash{$dsk}}) { # printf(" %d\n", $site); } # printf("\n"); } } my $results = timethese(1000000, { While => \&while_test, ForEach => \&foreach_test, }, 'none'); cmpthese( $results ); __END__ $ perl test.pl in.txt Rate While ForEach While 14286/s -- -10% ForEach 15898/s 11% --

Keep in mind that all the arrays that we use in the while loops are destroyed because of shift. In case that you do not need to use the arrays again try this it should give a small boost.

Hope this helps, BR.

Seeking for Perl wisdom...on the process of learning...not there...yet!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1196103]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-04-25 23:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found