To avoid excessive allocation & garbage collection for performance critical applications, I sometimes use the following approach (simplified):
buffer = pointer(Vector{UInt8}(undef, 100))
function alloc(::Type{T}, n, offset) where T
size = n * sizeof(T)
ptr = buffer + offset
unsafe_wrap(Vector{T}, convert(Ptr{T}, ptr), n), offset + size
end
julia> offset = 0
0
julia> a, offset = alloc(Int, 2, offset)
([4627565936, 4627565936], 16)
julia> a, offset = alloc(Float64, 2, offset)
([2.2864006326e-314, 2.394940531e-314], 32)
This works for any isbits
type. Is it possible directly interpret a chunk of memory as a vector of isbitsunion
elements, .e.g. Union{Nothing, Int64}
? I couldn’t find anything in docs and unsafe_wrap
doesn’t work either:
julia> a = unsafe_wrap(Vector{Int64}, pointer([1,2,3]), 3)
3-element Vector{Int64}:
1
2
3
julia> a = unsafe_wrap(Vector{Union{Nothing, Int64}}, pointer([1,2,nothing]), 3)
ERROR: ArgumentError: unsafe_wrap: unspecified layout for union element type
Stacktrace:
[1] #unsafe_wrap#81
@ ./pointer.jl:89 [inlined]
[2] unsafe_wrap(::Type{Vector{Union{Nothing, Int64}}}, p::Ptr{Union{Nothing, Int64}}, d::Int64)
@ Base ./pointer.jl:89
[3] top-level scope
@ REPL[76]:1