Tech Tips: Handling Int Vectors in Perl 5

Hi all, and Happy Shavuoth.

The Tips

Apparently, perldoc -f vec writes 16-bit / 32-bit / 64-bit quantities in big endian byte order, including on little endian architectures such as x86. This may cause issues when writing XS / etc. bindings.

I ended up using the following approach on x86-64 Linux to overcome that:

use Inline C => <<"EOF", clean_after_build => 0;
#include <byteswap.h>
void add(SV * v_proto, size_t top, ssize_t dest)
{
    uint64_t *V = SvPV_nolen(v_proto);
    uint64_t last = bswap_64(V[0]);
    for (size_t i =1 ;i <= top;++i)
    {
        const uint64_t next = bswap_64(V[i]);
        V[ ++dest] = bswap_64(next + last);
        last = next;
    }
}
EOF

It likely will not work elsewhere.

After doing that, I decided to try PDL only to discover that when used on x86-64 mageia linux v7, its long() type was 32-bits and I had to use longlong(). The end of the story is that I ended up using a different approach which I have implemented in Julia (but which I think would also be functional if implemented in Perl 5) and which worked faster.

Media Recommendation

I enjoyed this 90's Pop Mashup in case that is your thing.

Recommended Blog Post

"Why I'm still using jQuery in 2019" which made me feel less guilt. ( Hacker News and via Halinkiyah.)

Licence

The text is Copyright by Shlomi Fish 2019 under CC-BY 4.0. You can freely reuse the source code under your choice of the MIT/Expat License or the Public Domain/CC0.

Leave a comment

About Shlomi Fish

user-pic An Israeli software developer, essayist, and writer, and an enthusiast of open/free software and cultural works. I've been working with Perl since 1996.