function y_from_x!(y, x)
interesting_indices = [7, 2, 4]
for i in keys(interesting_indices)
y[i] = x[interesting_indices[i]]
end
end
a=collect(2:9)
b=zeros(3)
y_from_x!(b,a)
then b is [8.0,3.0,5.0] as expected
I would like to write this cleaner and more importantly with better performance (for bigger “interesting_indices”, x and y vectors)
I already found y[:] = getindex(x, interesting_indices), but getindex allocates a new array, right? that would be bad performancewise, right?
Any ideas?
Also: would it be better to make the interesting_indices a const? they wont change…
Thanks
I don’t think you can really improve the performance of this much from where you are, short of not allocating the interesting_indices array every call. For example, you could use a tuple interesting_indices = (7,2,4) to not allocate.
You are correct that getindex allocates a new array when called for an array of indices. But you can use broadcasting over getindex to perform it all in terms of scalar getindex (which does not allocate):
y .= getindex.(Ref(x), interesting_indices)
Broadcasting is not intrinsically faster than a loop, but it does tend to avoid excess boundschecks that might otherwise might happen if you aren’t careful in writing the loop.
Having interesting_indexes as a global variable may limit your flexibility and/or performance. Maybe you just need to pass this array as a parameter. Also you can write that in one line, if you want it to be concise:
y_from_x!(x,y,interesting_indexes) = y .= @view x[interesting_indexes]
If you have to create y for every new set of interesting indexes, than the fastest way to do it is something like:
y_from_x!(x,y,interesting_indexes) = y .= @view x[interesting_indexes]
function y_from_x(x,interesting_indexes)
y = similar(x, length(interesting_indexes))
return y_from_x!(x,y,interesting_indexes)
end