I think multiple dispatch is your answer here. There might be variants of selectdim which would work for a list of indices but I’m not aware of them.
About performance itself, two little tips:
- don’t forget to interpolate global variables when you use BenchmarkTools.jl
- try array views to avoid allocations (not always faster, see below)
const AV = AbstractVector
const AM = AbstractMatrix
partialcopy!(x::AV, y::AV, rows) = x .= y[rows]
partialcopy!(x::AM, y::AM, rows) = x .= y[rows, :]
partialcopy2!(x::AV, y::AV, rows) = x .= @view y[rows]
partialcopy2!(x::AM, y::AM, rows) = x .= @view y[rows, :]
Setup code:
using BenchmarkTools, StatsBase
x, X = zeros(100), zeros(100, 1)
y, Y = ones(1000), ones(1000, 1)
rows = sample(1:1000, 100, replace=false)
Results:
julia> @btime partialcopy!($x, $y, $rows);
211.100 ns (1 allocation: 896 bytes)
julia> @btime partialcopy2!($x, $y, $rows);
113.900 ns (0 allocations: 0 bytes)
julia> @btime partialcopy!($X, $Y, $rows);
248.100 ns (1 allocation: 896 bytes)
julia> @btime partialcopy2!($X, $Y, $rows);
332.664 ns (0 allocations: 0 bytes)
Interestingly, the array views speed things up for vectors and slow them down for matrices. I think you’d actually be better served by writing out the loop explicitly here.