I’ve started a project in Erlang recently, and I needed a big block of mutable memory – a massive byte array, buffer, whatever you want to call it. Erlang’s binary strings are immutable and so probably not suitable.
I figured the core distribution must’ve had something like this … nope. Spending 30 minutes Googling and checking docs twice and thrice over, but there’s clearly no mutable byte array in Erlang itself.
Is there a hack that approximates to this? Search … this StackOverflow
almost seems
hopeful
at the end, referencing hipe_bifs:bytearray/2
and
hipe_bifs:bytearray_update/3
, but alas, they are so-named because they are
part of the HiPE native compiler, and not Erlang itself. (I’m not currently
using HiPE, and it would be nice to not be tied to it.)
Then, I thought, surely someone else has extended Erlang to do this. There are several modes of extending Erlang, but native implemented functions (NIFs) would be the obvious candidate for manipulating large chunks of memory.
Googling this yielded complete failure: people just don’t seem to be doing it. (If people are doing it and you know this, please, let me know.)
So I did it: k6_bytea.
The interface is simple and fairly pleasant:
The gigabyte allocation caused a small notch on my memory performance graph:
The obvious question remains: how does it perform, vis-à-vis binary strings?
Let’s make a contrived benchmark: initialise a large buffer, write all over it in a deterministic fashion, and copy data all over it. Let’s do it in parallel, too.
Here’s the benchmarking code for your perusal:
Over 3 runs, binary_strings
averaged 24,015ms, and k6_bytea
198ms
(0.83% time, or 121x speed).
There’s nothing very surprising about this; it’s large, unwieldy immutable data-structures vs. one mutable data-structure. It’s even the case that I have no idea if there are any better ways to simulate a byte array in Erlang, either with binary strings, or without!
The binary string-manipulating code above is ugly and error-prone, as it’s clearly not the purpose it was built for. If it should turn out that this really hasn’t been done better by someone else, then I encourage you to look to and improve k6_bytea for this purpose.