> > is it possible the ops to handle variable number of arguments, what I have
> > in mind :
> >
> > print I1,",",N2,"\n"
>
> This should be done by create array opcode plus print array opcode.
>
> [1, 2, 3, 4, 5]

I have a minor issue with a proliferation of createArray.  In perl5 we
used the Stack for just about everything minus physically setting @x =
(1,2,3).  The creation of a dynamic array is a memory hog. ESPECIALLY with
mark-and-sweep dynamic memory (which is sounds like perl6 is aiming for).

Lets say you wanted
for(...) {
  x++
  y++
  z++
  print "x=$x, y=$y, z=$z"
}
Then you'd possibly have

LOOP: cond_eq Ix, DONE
inc I1, 1
inc I2, 1
inc I3, 1
createArray P1, 6
setIndexOf P1, 0, "x="
setIndexOf P1, 1, I1
setIndexOf P1, 2, ", y="
setIndexOf P1, 3, I2
setIndexOf P1, 4, ", z="
setIndexOf P1, 5, I3
print P1
branch LOOP
DONE:

Obviously this could be written differently (say using 6 separate
print-statements.. but we're saying that print is slow, so we'd want to
minimize calls to it; possibly via performing an implicit join when
printing an array).  Additionally createArray could have happened on one
line, but that's not an issue either (this avoids type-issues).

In any case, what we've done here is dynamically create an array each time
through the loop.  Theoretically we could reuse the same array, but what
if instead of a loop this is part of a log function which happens to get
called a zilion times in debug mode.  For many types of gc-ers,
pointing to something new leaves the unreferenced data stranded until
we're either memory starved or a timer goes off.  In the case of a
createArray in an inner loop, we could segment the entire memory map into
chunks that fit this dynamic array before we starve for memory.  Depending
on the memory allocator, gcing that data will mean coallescing ALL of it
(potentially hundreds of meg worth).

Recently, there was an international programming contest for compressing
XML, and I wrote a program using perl.  Worked great, except when I used
input data on the order of a meg, I consumed 300-400meg worth of
user-memory.  No biggie, but when the program was finished (physically
output the result)  it took just as long to deallocate everything
(20minutes).  My guess is that the gnu memory allocator used by perl5 w/in
red-hat 7.1 did some heavy coallescing.  When I used perl5's shipped
memory allocator w/ no coallescing, the program exited in a nominal amount
of time (while saving some 100Meg of memory to boot).  Lets just say that
I developed a new fondness for the perl5 memory allocator.

The lesson I learned was to not take for granted dynamically allocated
memory).  A simple mark-and-sweep GC is going to have a major hickup
periodically with this sort of inner-loop allocation.  In this case
ref-counting would at least not leave a stragling allocation, and thus
would not micro-fragment / hickup.  I'm sure you can write the
mem-allocator to gc before fragmenting larger chunks, but it's still
excess CPU overhead for this task.

The point here is to avoid the use of dynamic allocation where possible;
especially with the internals.

This is a perfect use for the perl-stack, short and simple.

-Michael


Reply via email to