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

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.

  • Comment on Re^2: I am confused by a "Learning Perl" sample showing "unshift"

Replies are listed 'Best First'.
Re^3: I am confused by a "Learning Perl" sample showing "unshift"
by LanX (Cardinal) on Jan 22, 2021 at 22:41 UTC
    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:
        :-)

        No, as the first one changes @a, but the second one changes @b. The result is the same, but ends up in a different container.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        Yes good point! :)

        ( provided choroba's comment, that the targets are swapped. )

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

Re^3: I am confused by a "Learning Perl" sample showing "unshift" (updated)
by haukex (Bishop) on Jan 22, 2021 at 22:48 UTC
    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% --