in reply to Effecicncy of key-only hash

I'd do it with 1 as the hash values, because then you can simply write if ($hash{$key}), and hell doesn't break loose if you happen to forget the exists in front of it. And speaking from my own experience, at one point you will forget it.

Replies are listed 'Best First'.
Re^2: Effeciency of key-only hash
by betterworld (Curate) on Aug 24, 2008 at 10:35 UTC

    I agree that it's more comfortable to omit the "exists". However if you want to work with hash slices, it's not that easy to use "1"s.

    tilly's code:

    undef(@hash{qw(shave the modern way)});

    would have to be written like this:

    @hash{qw(shave the modern way)} = (1) x 4; # cumbersome
      I always do those inits as:
      my %hash = map {($_=>1)} qw(shave the modern way);
      I always found it to be a little more maintainable (i.e. readable) than the x operator trick.


      -pete
      "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
        my %hash = map {($_=>1)} qw(shave the modern way);
        Hurrah for this solution! One minor note: Since map evaluates the 'mapping block' in list context (as opposed to grep, incidentally), you can shave off two characters by omitting the parentheses.

        UPDATE: Thanks to betterworld for pointing out that, if map didn't already evaluate its mapping block in list context, then the parentheses wouldn't help.

        Its not a trick, its syntaxt :)
      The fact is, the exists seems to be really faster:
      use Benchmark qw(cmpthese); use strict; use warnings; $\="\n"; cmpthese 1000000, { empty_strings => sub { my %h = ( shave => '', the => '', modern => '', way => '', ); my $mod = defined $h{modern}; my $ant = not defined $h{antique}; our $went_empty; print( ($mod?'y':'n'), ', ', ($ant?'y':'n') ) unless $went_empty++ +; }, ones => sub { my %h = ( shave => 1, the => 1, modern => 1, way => 1, ); my $mod = $h{modern}; my $ant = not $h{antique}; our $went_one; print( ($mod?'y':'n'), ', ', ($ant?'y':'n') ) unless $went_one++; }, undefs => sub { my %h = ( shave => undef, the => undef, modern => undef, way => undef, ); my $mod = exists $h{modern}; my $ant = not exists $h{antique}; our $went_undef; print( ($mod?'y':'n'), ', ', ($ant?'y':'n') ) unless $went_undef++ +; }, one_big_undef => sub { my %h; undef @h{qw{shave the modern way}}; my $mod = exists $h{modern}; my $ant = not exists $h{antique}; our $went_big; print( ($mod?'y':'n'), ', ', ($ant?'y':'n') ) unless $went_big++; } }
      gives:
      y, y
      y, y
      y, y
      y, y
                        Rate empty_strings          ones        undefs one_big_undef
      empty_strings 319489/s            --          -18%          -20%          -29%
      ones          390625/s           22%            --           -2%          -14%
      undefs        398406/s           25%            2%            --          -12%
      one_big_undef 452489/s           42%           16%           14%            --
      
      
      []s, HTH, Massa (κς,πμ,πλ)

        Any of those executes at well over 300000 per second. How many seconds do you think you'll spend debugging a "failure to use exists"? Is the performance gain worth that? How many times would you have to run this program before the execution time gained exceeds the debugging time lost? How do you value your time versus execution time (note that you're coding in Perl, not C)?