Copying a NTuple{UInt8} into a Memory{UInt8} or Vector{UInt8}

In reviewing changes lead to StaticStrings.jl v0.3 I noticed the following code pattern would out perform other approaches including a plain for loop which does appear to vectorize.

To led to the following code which seemed to outperform other approaches:

@inline function bulk_copyto!(dest::AbstractVector{T}, doffs::Int,
                              src::NTuple{N,T}, soffs::Int, n::Int) where {T,N}
    @boundscheck begin
        isbitstype(T) && sizeof(NTuple{N,T}) == N*sizeof(T) || throw(ArgumentError("layout mismatch"))
        1 <= soffs && soffs+n-1 <= N && 1 <= doffs && doffs+n-1 <= length(dest) || throw(BoundsError())
    end
    ref = Ref(src)
    GC.@preserve ref dest begin
        p = Ptr{T}(Base.unsafe_convert(Ptr{Cvoid}, ref)) + (soffs-1)*sizeof(T)
        unsafe_copyto!(pointer(dest, doffs), p, n)
    end
    return dest
end

It seems that using this approach should be available via safe methods so I create the following issue:

I wanted to have a more general discussion here in case there is a reason for the current compiler behavior or the lack of a method to accelerate copying from a NTuple to Vector or Memory.

2 Likes