in reply to Re: Re: aliasing
in thread aliasing

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!

Replies are listed 'Best First'.
Re: Re: Re: Re: aliasing
by ysth (Canon) on Jan 12, 2004 at 23:26 UTC
    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!

        Goodness knows, there are optimizations lurking that are hard to spot, and there may be one for the @r = reverse @r, but if so I don't see it.

        The above (in pp_reverse) is only executed after the array has been moved onto the stack, and in your pseudo-code, @array represents the stack, not the array being reversed. What you quote is the general code for any list-context reverse, which just reverses everything from the MARK showing the beginning of reverse's arguments to the SP stack pointer at the top of the stack.

        I'm intrigued that @r = reverse 1,@r seems to take more memory; how much more?