Most efficient way to do `[maximum(x[:,j] .* W) for j in 1:size(x, 2)]` where `x` is a matrix and `W` is a vector

I have

W = rand(12)
x = rand(12, 1000)

and I would like multi each column of x by W element-wise then take the maximum of the column. I should end up with a vector with the same size as the number of coumns of x

The best way I can think of is

[maximum(x[:,j] .* W) for j in 1:size(x, 2)]

but I think there should a more efficient way

Actual, I wanted to do this in Flux.jl so the code is more like

# start random parameters
x = rand(12, 1000)
W = param([1 for i=1:12])
x1 = [maximum(x[:,j] .* W) for j in 1:size(x, 2)]
julia> using LazyArrays

julia> vec(maximum(BroadcastArray(*, W, x), dims=1));
3 Likes

There should be more efficient ways to do this, but I would do it as

maximum(x .* W, dims=1)

x .* W allocates an intermediate array of the same shape as x which is not necessary, hence my LazyArrays solution which doesn’t materialize the array.

Benchmarks:

julia> @btime [maximum($(x)[:,j] .* $W) for j in 1:size($x, 2)];
  110.080 μs (2003 allocations: 351.75 KiB)

julia> @btime vec(maximum(BroadcastArray(*, $W, $x), dims=1));
  42.240 μs (15 allocations: 8.30 KiB)

julia> @btime @views [maximum($(x)[:,j] .* $W) for j in 1:size($x, 2)];
  75.093 μs (2003 allocations: 226.75 KiB)
1 Like