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

Re: I am confused by a "Learning Perl" sample showing "unshift"

by LanX (Saint)
on Jan 22, 2021 at 21:07 UTC ( [id://11127309]=note: print w/replies, xml ) Need Help??


in reply to I am confused by a "Learning Perl" sample showing "unshift"

unshift is like push just from the lower side, kind of inverted shift

a little perldebugger demo

DB<9> x @a =(5) 0 5 DB<10> unshift @a,4 DB<11> x @a 0 4 1 5 DB<12> unshift @a,1,2,3 DB<13> x @a 0 1 1 2 2 3 3 4 4 5 DB<14> push @a, 6 DB<15> x @a 0 1 1 2 2 3 3 4 4 5 5 6 DB<16> p shift @a 1 DB<17> x @a 0 2 1 3 2 4 3 5 4 6 DB<18> p pop @a 6 DB<19> x @a 0 2 1 3 2 4 3 5 DB<20>

I recommend trying perl -de0 to play around by yourself

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: I am confused by a "Learning Perl" sample showing "unshift"
by KenAndrews (Initiate) on Jan 22, 2021 at 22:33 UTC

    Thanks for the response. My problem is not really what it's doing as that's obvious by the results. My problem is more the how.

    unshift when acting with one value is (sort of) moving everything up one slot, then filling in the new [0] slot.

    However, when acting with multiple values, is it:

    reversing the order of the incoming values then (move everything up one slot, fill in the new [0] slot) N times

    or

    count the incoming values, move everything up N slots, then fill in the N slots [0],[1],[2],... with the incoming values

    My personal bet is on the second as it'd be faster. Admitted, this is not one of the all-time consuming questions about the Universe, but when something doesn't act the way I expect, I like to know how it achieves the result(s) that it gets. Or should I simply go with "No, I won't pay any attention to the man behind the curtain."?

    And yes, thank you, I'll be fiddling with the debugger sooner or later.

      For reasons of symmetry this

      unshift @a, @b means @a = ( @b, @a )

      Much the same way as

      push @a, @b means @a = ( @a, @b )

      So no implicit reversing of @b.

      HTH :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Therefore:
        unshift @a, @b same* as  push @b, @a

        *But see clarification from choroba:
      Or should I simply go with "No, I won't pay any attention to the man behind the curtain."?

      Yes. Perl functions generally do what they say on the tin :-)

      Admitted, this is not one of the all-time consuming questions about the Universe, but when something doesn't act the way I expect, I like to know how it achieves the result(s) that it gets.

      As far as I can tell from the internal implementation of pp_unshift and av_unshift, your guess that it's the latter (Edit 2: that is, shift the array up by N at once) appears to be correct. But as stated above, that should be considered an implementation detail that you don't need to worry about.

      My personal bet is on the second as it'd be faster.

      If concerned about performance, always measure first, using Benchmark and/or Devel::NYTProf.

      Update: Actually, LanX's post here provides something more interesting to benchmark. I've also added a built-in test of the benchmarked code here.

      use warnings; use strict; use Benchmark qw/cmpthese/; use constant TEST => 0; my $EXP = join $", 100..150, 1..50; cmpthese(-2, { unshift => sub { my @array = 1..50; my @add = 100..150; unshift @array, @add; "@array" eq $EXP or die "@array" if TEST; }, loop => sub { my @array = 1..50; my @add = 100..150; unshift @array, $_ for reverse @add; "@array" eq $EXP or die "@array" if TEST; }, concat => sub { my @array = 1..50; my @add = 100..150; @array = ( @add, @array ); "@array" eq $EXP or die "@array" if TEST; }, }); __END__ Rate loop concat unshift loop 273062/s -- -19% -33% concat 337646/s 24% -- -18% unshift 409595/s 50% 21% --

Log In?
Username:
Password:

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

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

    No recent polls found