in reply to Trying to optimize de-referenced hash slice without scope variables...

In addition to the post above, I would think that just copying one scalar is not that big a deal. Remember that you're copying only the hash reference, not the complete %data hash.

In fact, if you use $_[3] a lot in the same function, it might even be slower than copying it to a lexical variable, because of the array indexing that needs to be done. (haven't benchmarked this at all, so I might be wrong)

  • Comment on Re: Trying to optimize de-referenced hash slice without scope variables...
  • Download Code

Replies are listed 'Best First'.
Re^2: Trying to optimize de-referenced hash slice without scope variables...
by meetraz (Hermit) on Jun 15, 2004 at 17:43 UTC
    use strict; use Benchmark qw(:all); my %data = ( Lore =>'mipsumdo', ente =>'squemoll', lors =>'itametco', isod =>'ioetnonu', nsec =>'tetuerad', mmyf =>'acilisis', ipis =>'cingelit', augu =>'eliberoi', Sedr =>'honcusma', acul =>'isodioat', ssai =>'dmollisp', cons =>'ectetuer', hare =>'travelit', nisl =>'nislquis', null =>'amattise', feli =>'sDonecma', nimq =>'uisferme', gnar =>'isusulla', ntum =>'nequenul', mcor =>'peridele', lase =>'dduiDone', ifen =>'dutfeugi', cbla =>'nditmetu', atas =>'emAliqua', svit =>'aecondim', msed =>'magnaado', entu =>'mluctusa', lorn =>'onummysa', ntem =>'assaeuis', gitt =>'isNuncne', moda =>'nteaport', corc =>'iMorbima', amii =>'psumnonl', ttis =>'blandits', eoAl =>'iquamcon', emPh =>'asellusq', dime =>'ntumblan', uiso =>'rciInfer', ditf =>'elisPell', ment =>'umturpis', ); sub WithCopy { my $hashref = $_[0]; my @dummy = @{$hashref}{'Lore','lors','nsec'}; } sub WithoutCopy { my @dummy = @{$_[0]}{'Lore','lors','nsec'}; } cmpthese(5000000, { 'WithCopy' => 'WithCopy(\%data);', 'WithoutCopy' => 'WithoutCopy(\%data);', }); __END__ Rate WithCopy WithoutCopy WithCopy 548908/s -- -6% WithoutCopy 581801/s 6% --
      On my machine that gives (with 500000 iterations)
      Rate WithCopy WithoutCopy WithCopy 450450/s -- -9% WithoutCopy 495050/s 10% --
      But if you access the hashref more than once in the functions - say about 10 times:
      use strict; use Benchmark qw(:all); my %data = ( Lore =>'mipsumdo', ente =>'squemoll', lors =>'itametco', isod =>'ioetnonu', nsec =>'tetuerad', mmyf =>'acilisis', ipis =>'cingelit', augu =>'eliberoi', Sedr =>'honcusma', acul =>'isodioat', ssai =>'dmollisp', cons =>'ectetuer', hare =>'travelit', nisl =>'nislquis', null =>'amattise', feli =>'sDonecma', nimq =>'uisferme', gnar =>'isusulla', ntum =>'nequenul', mcor =>'peridele', lase =>'dduiDone', ifen =>'dutfeugi', cbla =>'nditmetu', atas =>'emAliqua', svit =>'aecondim', msed =>'magnaado', entu =>'mluctusa', lorn =>'onummysa', ntem =>'assaeuis', gitt =>'isNuncne', moda =>'nteaport', corc =>'iMorbima', amii =>'psumnonl', ttis =>'blandits', eoAl =>'iquamcon', emPh =>'asellusq', dime =>'ntumblan', uiso =>'rciInfer', ditf =>'elisPell', ment =>'umturpis', ); sub WithCopy { my $hashref = $_[0]; my @dummy1 = @{$hashref}{'Lore','lors','nsec'}; my @dummy2 = @{$hashref}{'Lore','lors','nsec'}; my @dummy3 = @{$hashref}{'Lore','lors','nsec'}; my @dummy4 = @{$hashref}{'Lore','lors','nsec'}; my @dummy5 = @{$hashref}{'Lore','lors','nsec'}; my @dummy6 = @{$hashref}{'Lore','lors','nsec'}; my @dummy7 = @{$hashref}{'Lore','lors','nsec'}; my @dummy8 = @{$hashref}{'Lore','lors','nsec'}; my @dummy9 = @{$hashref}{'Lore','lors','nsec'}; my @dummy0 = @{$hashref}{'Lore','lors','nsec'}; } sub WithoutCopy { my @dummy1 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy2 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy3 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy4 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy5 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy6 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy7 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy8 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy9 = @{$_[0]}{'Lore','lors','nsec'}; my @dummy0 = @{$_[0]}{'Lore','lors','nsec'}; } cmpthese(500000, { 'WithCopy' => 'WithCopy(\%data);', 'WithoutCopy' => 'WithoutCopy(\%data);', }); __END__ Rate WithoutCopy WithCopy WithoutCopy 82645/s -- -8% WithCopy 89445/s 8% --

      Which seems to show that the performance increase is less when you index the @_ array a lot.

      Of course it doesn't show that - it could also mean that the time needed to copy the keys of the hash reference 10 times overshadows the time needed to index the array and/or copy the hash reference, thereby decreasing the influence of doing either.

      Benchmarking is hard.

Re^2: Trying to optimize de-referenced hash slice without scope variables...
by monsieur_champs (Curate) on Jun 15, 2004 at 17:36 UTC

    Interesting point. I use $data 8 times. Half as a boolean test (no de-reference) and half as a hash reference (to recover one or more values). I guess (and maybe I'm wrong about this) that it doesn't worth the benchmark...

    Here is the complete function code:

    sub inputBox{ # Don't uncomment, use @_ instead # my $action_url = shift; # $_[0] # my $msgid = shift; # $_[1] # my $action = shift; # $_[2] my $data = $_[3]; # oh, I needed this one, I wasn't able to use a ha +sh-slice from a hash-reference in one shot. <readmore> return qq{<form action="$_[0]" method="post">\n}. ($_[1]? qq{ <input type="hidden" name="message_id" value="$_[1]" />\n +}:''). qq{ <input type="hidden" name="action" value="$_[2]" /> <input type="hidden" name="commit" value="1" /> <table align="center" border="1" cellpadding="5" cellspacing="0"> <tr valign="middle" align="center" bgcolor="$color{TABLE_HEAD}"> <td colspan="2"> } .($_[2] eq 'edit'? "Edit Message #$_[1]" : 'Compose New Message' ). qq{ </td> </tr> <tr valign="middle" align="left" > <td> Author: </td> <td> }.( $_[2] eq 'edit'? q{ <input type="text" name="author" size=" +40" }. ( $data? qq{value="$data->{author}"} : &TWiki::Func::getWikiUserName +() ) . qq{ />} : &TWiki::Func::getWikiUserName() ) . q{ </td> </tr> <tr valign="middle" align="left"> <td>Due Date: </td> <td>} . &gen_date_selector( 'due', ( $data? @$data{'day','month' +,'year','hour','minute'} : (localtime)[5]+1900, (localtime)[4]+1, (lo +caltime)[3], 23, 59 ) ) . qq{ </td> </tr> <tr valign="middle" align="left"> <td>Message: </td> <td> <textarea rows="5" name="msg" cols="50">}.($data? $data->{msg} + : '' ).qq{</textarea> </td> </tr> <tr valign="middle" align="left"> <td> <input type="checkbox" name="dropped" value="Y" }.($data && $d +ata->{dropped} eq 'Y'? 'CHECKED':'' ).q{>&nbsp;Dropped. </td> <td align="right"> <input type="submit" name="change" value="Change Message"> </td> </tr> </table> </form> }; }