Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^3: Using 'keys' on a list

by Marshall (Canon)
on Jul 07, 2021 at 00:42 UTC ( [id://11134742]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Using 'keys' on a list
in thread Using 'keys' on a list

I liked your idea of adding a "baseline"!
I also really don't know either why generating the list of keys in the sub appears to be faster then giving the caller the ref and having him do it? I would have expected that difference to be smaller. Hopefully some other Monk knows?

However, the main point remains: If the caller needs the whole hash, give him a ref to a hash. This is much faster than passing the entire hash back as a list. Of course there are memory allocation issues with that because Perl will keep the memory for that hash allocated as long as there is reference to it.

Added: Except as a part of an object method, I don't know why a sub() in general would create a hash, only to just pass back just the keys? Seems a bit weird, but I'd also like to know why this appears to be somewhat faster.

Replies are listed 'Best First'.
Re^4: Using 'keys' on a list
by GrandFather (Saint) on Jul 07, 2021 at 01:58 UTC
    "I don't know why a sub() in general would create a hash, only to just pass back just the keys?"

    There are likely to be lots of reasons, but a simple one is to generate a list of unique results from some process.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      Yes, although standard Perl idioms can do that without a named sub (i.e., get just the unique hash key names). I could envision an OO object that returns just the keys of a hash via a method call that represents the "persistent data" related to that object. In a non-OO program, the normal thing would be to return a reference to the created hash (i.e. the values are significant and needed for further processing). I don't see any disagreement here.
      I just tested my benchmark code to see if it is doing what I think that is doing.

      My eyes can certainly be deceived, but why does generating the list of keys in the sub and passing copy of that list to the caller appear to be faster than passing a ref to the caller and having him generate this list his own?

        In terms of the relative speeds, running the code through B::Concise is maybe helpful.

        I can't interpret the full details, but the code to return a list of keys has fewer operations and only one nextstate (so less bookkeeping?). Both have the same number of ops that are optimised away (those preceded by "ex-").

        Hopefully someone with better knowledge of the internals and B::Concise can shed some light.

        C:\path>perl -v | find "This is" This is perl 5, version 28, subversion 0 (v5.28.0) built for MSWin32-x +64-multi-thread
        C:\path>type return_hash_keys.pl use strict; use warnings; sub zort { my %hash = (a => 1); return keys %hash; }; my @x = zort(); #my $aa = $x[0]; C:\path>perl -MO=Concise,-src return_hash_keys.pl a <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 # 7: my @x = zort(); 2 <;> nextstate(main 6 return_hash_keys.pl:7) v:*,&,{,x*,x&,x$,$ - +>3 9 <2> aassign[t2] vKS/COM_AGG ->a - <1> ex-list lK ->7 3 <0> pushmark s ->4 6 <1> entersub lKS/STRICT ->7 - <1> ex-list lK ->6 4 <0> pushmark s ->5 - <1> ex-rv2cv sK/STRICT,1 ->- 5 <#> gv[IV \&main::zort] s ->6 - <1> ex-list lK ->9 7 <0> pushmark s ->8 8 <0> padav[@x:6,7] lRM*/LVINTRO ->9 return_hash_keys.pl syntax OK
        C:\path>type return_hash_ref.pl use strict; use warnings; sub zort { my %hash = (a => 1); return \%hash }; my $x = zort(); my @x = keys %$x; #my $aa = $x[0]; C:\path>perl -MO=Concise,-src return_hash_ref.pl g <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 # 7: my $x = zort(); 2 <;> nextstate(main 6 return_hash_ref.pl:7) v:*,&,{,x*,x&,x$,$ -> +3 7 <2> sassign vKS/2 ->8 5 <1> entersub sKS/STRICT ->6 - <1> ex-list sK ->5 3 <0> pushmark s ->4 - <1> ex-rv2cv sK/STRICT,1 ->- 4 <#> gv[IV \&main::zort] s ->5 6 <0> padsv[$x:6,8] sRM*/LVINTRO ->7 # 8: my @x = keys %$x; 8 <;> nextstate(main 7 return_hash_ref.pl:8) v:*,&,{,x*,x&,x$,$ -> +9 f <2> aassign[t6] vKS/COM_AGG ->g - <1> ex-list lK ->d 9 <0> pushmark s ->a c <1> keys[t5] lK/1 ->d b <1> rv2hv[t2] lKRM/STRICT ->c a <0> padsv[$x:6,8] sM/DREFHV ->b - <1> ex-list lK ->f d <0> pushmark s ->e e <0> padav[@x:7,8] lRM*/LVINTRO ->f return_hash_ref.pl syntax OK

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2024-03-28 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found