http://qs1969.pair.com?node_id=42437


in reply to Sort this data

UPDATE

As per my revelations in sort this data, here is a bit of an adjusted report on the av.c source.
Here's the relevant portion from av.c in the 5.6 source:
/* this is Perl_av_unshift() it unshifts 'num' undef values to an array */ /* determine how much non-used spaced is left that's been allocated for this array */ i = AvARRAY(av) - AvALLOC(av); /* if there's room left... */ if (i) { /* if there's more room than we need, just use 'num' */ if (i > num) i = num; /* this will set 'num' to 0 if we had enough room */ /* 'num' is now how many new undef values we need added */ num -= i; AvMAX(av) += i; /* set the highest subscript??? */ AvFILLp(av) += i; /* add to highest subscript */ SvPVX(av) = (char*)(AvARRAY(av) - i); /* where Perl's array starts +*/ } /* if there wasn't enough room already... */ if (num) { i = AvFILLp(av); /* highest subscript */ av_extend(av, i + num); /* extend array to i+num elements */ AvFILLp(av) += num; /* add to highest subscript */ ary = AvARRAY(av); /* get at the array */ Move(ary, ary + num, i + 1, SV*); /* slide elements up */ do { ary[--num] = &PL_sv_undef; /* set new elements to undef */ } while (num); }
Ok, so unshift() has to do a lot of sliding the elements up if there's not already some free space generated by a call to shift().

What shift() does is simply slide the pointer up one notch, which is very fast (which provides free space for unshift() later). It stores the value in *AvARRAY(av) into retval, and then sets *AvARRAY(av) to the C equivalent of Perl's undef value. Then it moves the pointer that marks the beginning of the array to AvARRAY(av) + 1. It also subtracts one from the max subscript and the length of the array. Then it returns retval.

<revelation>I'm beginning to grok the source code! Look out!</revelation>.

japhy -- Perl and Regex Hacker