Tels <[EMAIL PROTECTED]> writes:
>> At first I thought this was due to size-considerations. However,
>
>That was the idea. I thought that a SV always has a IV, NV and PV slot, so 

It doesn't. See Gisle's diagrams.
SV * has ONE pointer to a separately allocated "something".
The least memory case for an XS object is the SvPV one with a C 
struct "hidden" as binary data in the "string".
This saves one C level indirection in speed, and one.

>Bigint is:
>
>       4 (int on my system)
>       8 (double on my system)
>       4 (ptr on my system)

Hmm. Probably makes sense to order that 
so two 4-bit things are adjacent.

>
>That makes 16 bytes. If I malloc this, it probably needs 16 bytes (malloc 
>might padd!), and storing an PTR in the IV of the SV needs:

On a 32-bit machine...

The fixed part of overhead for an Object in perl is:
  The SV * for the reference needs 3 words.
  The XRV * of that reference SV needs 1 word.
  The SV * for the object needs 3 words.

Then you have the representation cost.
  An SvIV costs one word for IV slot 
     + malloced struct costs N words+sysmalloc overhead
vs 
  An SvPV costs 3 words (ptr,cur,len), 
     + N words + perlmalloc overhead.

So the PV costs two more words in the trivial case, but saves 
one level of indirection on access.

Note that all perl's odd-sized structs are allocated in chunks.
So that we get (say) 1000 1-word XRV * from perlmalloc,
and then hand them out on newRV() to SVs till we run out.
In another place we got say (say) 330 3-word XPVs from malloc 
and hand those on newPV() 

>
>38 bytes, so the malloc() strategy would actually be less (IIAC). Why is the 
>SV bigger? CUR/LEN overhead?

As soon a you print (or otherwise stringify) a numeric 
it goes from being a bare NV or IV to PVIV and gains a allocated 
string for the stringified thing.

>
>Actually, I am not sure whether Devel::Size is even correct:

Perl code that gropes internals runs the risk of disturbing the state.
Bit like quantum mechanics...

>
>       # perl -MDevel::Peek -le '$a = "8"; $b = 8; $a = 8; $a += 0.9; $b = 9;
>       print Dump($a),Dump($b)'
>
>Anyway it really seems the malloc()/free() strategy might take less memory. 

Maybe (I am skeptical), but if you malloc it is in SvIV
and you get an extra indirection.

I have found over the last 9 years or so that puting data in PV
is reasonable way to go. Tk does this for small structs, 
and Audio::Data does this for large arrays of 'float'. Seems to 
work well enough in both cases.

>
>> But when using all three slots in a clever way it has the advantage that
>> at least the IV slot can be accessed from a Perl script, namely in
>> numeric context.

But beware perl thinking it knows what it is doing in such cases.
It will only use the IV slot if SvIOK is set, but if it isn't and 
there is an SvPOK set then it will do perl's conversion 
of string to IV and overwite your IV. Possibly worse if you say 
it has IV and it wants a string it is likely to convert IV to string
and write it over the SvPV slot.

>
>I wouldn't allow this, though :) 

Good.


Reply via email to