(I was going to post this as an issue on the Julia github, but I still feel I’m a little naive in this topic so I wanted to open it up to discussion here, see what people think, then post a real issue. I know there’s a little bit about this stuff in existing issues, but it seemed important to make sure everything was explicit and in one place, and I didn’t see an issue like that.)
I’ve just gotten through a fairly big IO project in which large amounts of data has to be loaded from and written from Vector{UInt8}
buffers efficiently. Early on, I had hoped that the new reinterpret
function would make it possible for me to do this without the use of Ptr
s, but I soon came to realize that this does not seem like it will be possible any time soon. I also fell victim to the tribulations of using pointers to wrap arrays in a language with garbage collection (can be very counter-intuitive if you’re coming from C or C++), so I therefore emphatically agree that ideally we do not want users to make use of pointers. The more of this kind of code is around the worse it will be for the stability of the Julia ecosystem.
Here are the things which I believe have to be done to get there, and a few suggestions.
reinterpret
must be a no-op (including indexing)
(except possibly for some simple bounds checking) Since IO is performance critical it is absolutely crucial that reinterpret
or its future equivalent be a no-op, and that indexing the resulting array must be an absolutely minimal operation. I’ve looked at the code for reinterpret
and improving it certainly looks daunting. I have to confess that I don’t fully understand everything that’s being done there.
Suggestions:
- From looking at
reinterpret
it seems possible that we will need a dedicated function for certain alignments (i.e. wherever a no-op is possible and safe). Ideally that’s not the case, but I think we should be open to the possibility. - It’s ok if non-scalar indexing a
ReinterpretArray
returns new copiedArray
s. After all, indexing ofArrays
returns copies not views. This is not the current behavior ofReinterpretArray
, right now indexing returns anotherReinterpretArray
which is essentially a view (the inconsistency withArray
is confusing to me, I don’t see why this was done). This should be simple to achieve by anunsafe_wrap
followed by acopyto!
of a newly constructed array (it has zero overhead, I’ve tested it). You can always haveview
return either aReinterpretArray
or aSubArray
. Iterating over either of these should be a no-op for each scalar index.
need to be able to reinterpret
from arrays of smaller elements to scalars of a larger data type as a no-op
Granted, if ReinterpretArray
works perfectly this wouldn’t be strictly necessary but it’s something we definitely should have. Without it, packages must be carefully designed around it, and that does not seem ideal. Right now if you try to do this you instead get a 1-element array, the creation of which comes with significant overhead.
users need a clear understanding of what happens for non-Array
AbstractArray
types
It should go without saying that the aforementioned no-ops are only possible in cases where data is actually adjacent. If that’s not the case, one would have to resort to some alternative, perhaps copying code into an IOBuffer
. I think we may need a version of reinterpret
that throws an error if you attempt to use it on some array where data is not adjacent. I think the possibility of this occurring is the primary reason for the current complexity of ReinterpretArray
. At the moment things seem a little precarious: for example if someone were to create an IO
buffer with a custom array type (e.g. MMapArray
) a user would have to go in and figure out how to actually unsafe_wrap
the data from raw Array
s and this might be a little scary if you don’t know the layout. (I don’t know of any reason why you’d actually need some sort of MMapArray
but I’ve been paranoid about something like that happening.)
Ok, am I missing any major points here? Did I say anything idiotic? Please share your thoughts if you have any and I’ll post an issue. Perhaps if consensus coalesces quickly I can start work on a PR. Thanks all!