in reply to Re: aliasing
in thread aliasing

I can't comment on your memory statistics, but I definitely see a list-context rv2av or padav for reverse @r, so each element of the array does appear to be put onto the stack.
$ perl -MO=Concise -we'@r = reverse @r' c <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 b <2> aassign[t6] vKS/COMMON ->c - <1> ex-list lK ->8 3 <0> pushmark s ->4 7 <@> reverse[t5] lK/1 ->8 4 <0> pushmark s ->5 6 <1> rv2av[t4] lK/1 ->7 5 <#> gv[*r] s ->6 - <1> ex-list lK ->b 8 <0> pushmark s ->9 a <1> rv2av[t2] lKRM*/1 ->b 9 <#> gv[*r] s ->a -e syntax OK $ perl -MO=Concise -we'my @r; @r = reverse @r' c <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 3 <0> padav[@r:1,2] vM/LVINTRO ->4 4 <;> nextstate(main 2 -e:1) v ->5 b <2> aassign[t3] vKS/COMMON ->c - <1> ex-list lK ->9 5 <0> pushmark s ->6 8 <@> reverse[t2] lK/1 ->9 6 <0> pushmark s ->7 7 <0> padav[@r:1,2] l ->8 - <1> ex-list lK ->b 9 <0> pushmark s ->a a <0> padav[@r:1,2] lRM* ->b -e syntax OK

Replies are listed 'Best First'.
Re: Re: Re: aliasing
by BrowserUk (Patriarch) on Jan 12, 2004 at 22:55 UTC

    I have to reverse (sic:) your statement. I can't comment on your opcode dumps -- I don't understand them enough.

    However, it should be fairly simple to test my assertions on the memory consumption.

    I used win32's task manager, but if you inserted a few <>; statements in place of the comments in the snippets I posted, you should be able to use top in another console to watch the memory usage and growth.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!

      I think what's happening is that the original assignment @r = 1..1000000 is expanding perl's stack to accomodate a million entries. Then reverse @r doesn't require any additional space. But the million entries are still put on the stack and then assigned.

        The relevant piece of code is this

        if (GIMME == G_ARRAY) { MARK++; while (MARK < SP) { tmp = *MARK; *MARK++ = *SP; *SP-- = tmp; } /* safe as long as stack cannot get extended in the above */ SP = oldsp; }

        which is roughly equivalent to

        ( $MARK, $SP ) = ( 0, $#array ); while( $MARK < $SP ) { $tmp = $array[ $mark ]; $array[ $MARK++ } = $array[ $SP ]; $array[ $SP-- ] = tmp; }

        which suggests that if the argument to reverse is a single array, rather than stack the array to create @_, the stack pointer is effectively pointed at the top of the array. This is born out (but not confirmed--I can;t find the relevant part of the source) by doing

        @r = reverse 1, @r;

        when substantial memory growth occurs. In this case, @_ has to be built fresh to incorporate the extra element.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        Timing (and a little luck) are everything!