in reply to Need for (XS) speed

If it's known that inside an AV* array all the elements are IVs

The elements are never IVs (an integral type big enough to hold an int and big enough to hold a pointer). They are always scalars (SVs).

And no, it's takes too little to convert the type of the SV body to make your plan workable. For example, just by printing the element, you can drastically change it's structure:

use Devel::Peek; $a[0] = 123; Dump $a[0]; print "$a[0]\n"; Dump $a[0];
SV = IV(0x238b30) at 0x238b34 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 123 123 SV = PVIV(0x182005c) at 0x238b34 REFCNT = 1 FLAGS = (IOK,POK,pIOK,pPOK) IV = 123 PV = 0x23f23c "123"\0 CUR = 3 LEN = 4

(Technically, it's the stringification for the concatenation that caused the conversion.)

You could access the SVs in the array via some pointer then use the normal SV macros to get the IV from them. But at this point, you gotta wonder what you are doing using a Perl array. Or Perl. One subroutine call would annihilate any savings.

Replies are listed 'Best First'.
Re^2: Need for (XS) speed
by spx2 (Deacon) on Mar 05, 2010 at 06:22 UTC

    yes you are right, I meant the _SV_HEAD_UNION member of SV*(corrected).let's suppose I won't ever print the element, I am just interested to use Perl's data structure for storage. btw, will pack/unpack alter it the same way print does ?(do you think I could get a relative pointer directly to the _SV_HEAD_UNION member ?)

    But at this point, you gotta wonder what you are doing using a Perl array. Or Perl.

    True, true ... but I am just decoupling the part that needs speed from the Perl part(which has different advantages such as abstraction, which I like).

      Isn't SvIVX what you're asking for? It's a version of SvIV optimised for the very condition you told us to assume.
      #define SvANY(sv) (sv)->sv_any #define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv

      I am just interested to use Perl's data structure for storage.

      Then use a string as a C array like BrowserUk suggested, with the following changes:

      • You want one of pack 'j' (IV), pack 'J' (UV), pack 'i' (I32) or pack 'I' (U32). It's not constant to which of those 'V' refers.
      • Using SvPVX instead of SvPVbyte makes needless assumptions.
        Using SvPVX instead of SvPVbyte makes needless assumptions.

        I'm sorry to have to start this all over again, but you are wrong. And here is why you are wrong.

        The only thing that it makes sense to pass to a routine expecting a scalar containing a string of packed integers, is exactly that.

        • An SV without a PV won't cut it. It'll trap.
        • An SV containing just an IV, UV, or NV won't cut it

          Even if it was forced to a PV, because treat that as a C array I'll get garbage.

        • An SV containing a PV that is UTF8=1 won't cut it.

          If it is downgraded to bytes and then I address it as a C array of ints, I'll get garbage.

        • An SV with magic attached won't cut it.

          Treat it as a C int array and I'll get garbage.

        The only useful behaviour of those, is the trap. Because it tells me that I haven't passed a packed scalar. Immediately, and unambiguously.

        If however, I call SvPVbyte, it won't prevent me from getting a trap if I pass an SV without a PV. But it will turn all the other cases into a piece of memory that there will be no way to discern was not a packed scalar of integers until I start getting garbage results.

        And it could take me a long time to trace the source of that garbage back to the error.

        The only assumption using SvPVX makes, is that I have passed a properly packed array. And if I haven't, it traps immediately, which tells me exactly where the problem lies.

        In other words, the only assumption it makes, is that I know what I'm doing-- and immediately tells me, in no uncertain terms, if I do not.

        And that's an invaluable behaviour in any piece of software!

        I do not expect you to agree, nor want you to respond.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        And if you have a library already allocating the memory, you can even reuse it if you use the string approach. Create a reference to a blessed scalar, assign to the scalar's PV the block of memory you got from the library, and set its SvLEN to zero so Perl won't try to free it. You can free it properly from your destructor (thus the reason for blessing).