Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

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

by monsieur_champs (Curate)
on Jun 15, 2004 at 17:01 UTC ( [id://366949]=perlquestion: print w/replies, xml ) Need Help??

monsieur_champs has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks
First of all, this is not homework. I have a real problem behind this and can send full source code of my (unpublished) TWiki's MessageBoardPlugin if you want to see it.

My problem is optimization. I'm sure that using @_ instead of copying functions args to scopped variables is faster, and need to use this here:

# inputBox( $url, $msgid, $action, \%data ) sub inputBox{ my $data = $_[3]; # some code here... # some processing here... return $result . map this($_), # hash de-ref and slicing at the same time... # however, can't do this with $_[3], syntax error. @$data{'a','b','c','d'};

I would like to use $_[3] instead of $data, but I can't, it generates a syntax error.

So what I need is a way to slice a de-referenced hash in just one shot. Any sugestions?

Thank you very much for your help.

Replies are listed 'Best First'.
Re: Trying to optimize de-referenced hash slice without scope variables...
by borisz (Canon) on Jun 15, 2004 at 17:15 UTC
    write:   @{$_[3]}{'a','b','c','d'}; since perl reads it as @{$_}[3]{...} otherwise.
    Boris

      Fellow boriz
      Thank you very much for your suggestion, but I'm not sure if

      perl -MData::Dumper -e "print Dumper @{$_[3]}{'a','b','c','d'}, $_[3]; + " $VAR1 = undef; $VAR2 = undef; $VAR3 = undef; $VAR4 = undef; $VAR1 = undef; $VAR2 = undef; $VAR3 = undef; $VAR4 = undef; $VAR1 = undef; $VAR2 = undef; $VAR3 = undef; $VAR4 = undef; $VAR5 = '1';
      is the same thing as
      perl -MData::Dumper -e 'print Dumper @$data{"a","b","c"}, $data' $VAR1 = undef; $VAR2 = undef; $VAR3 = undef; $VAR4 = { 'c' => undef, 'a' => undef, 'b' => undef };
      or I'm doing something really wrong here, or your data structure definition is not the same as my example. :-) Nice try, anyway.
        My perl works this way, Im sure there is another mistake.
        #!/usr/bin/perl use Data::Dumper; %xx = ( a => 1, b => 2 ); sub inputBox{ @{$_[3]}{'a','b','c','d'}; } sub inputBox2{ my $data = $_[3]; @$data{'a','b','c','d'}; } print Dumper (inputBox( 1,2,3,\%xx)); print Dumper (inputBox2( 1,2,3,\%xx));
        Boris
Re: Trying to optimize de-referenced hash slice without scope variables...
by Joost (Canon) on Jun 15, 2004 at 17:26 UTC
    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)

      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.

      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> }; }
Re: Trying to optimize de-referenced hash slice without scope variables...
by revdiablo (Prior) on Jun 15, 2004 at 20:55 UTC

    Like Joost, I am a bit skeptical about the need for this "optimization." If the performance of your application hinges on the speed of accessing subroutine arguments, then I think Perl might not be the right choice. Have you done any profiling to see if this is the case, or are you simply stabbing in the dark? I suggest you do the former, rather than the latter, when it comes to expending time and effort to optimize your code.

      Dear fellow revdiablo

      In fact, you're right about this: I'm stabbling in the dark.

      But I'm not alone: this is a standard (?), required (?) optimization for TWiki Plugins like this and this.

      Maybe I shall alert the main project developers about this "optimization".

      Thank you for the insight.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://366949]
Approved by cLive ;-)
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-04-19 07:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found