Broadcasted assignment slower than for loop when indices are arbitrary

Ok this seems to be working fine (not as fast as writing a for loop but a “good” compromise):

function set_awfb!(func::F, a, w, b::Vararg{T, N}) where {F, T, N}
    for i in w
        @inbounds a[i] = func(map(x -> x[i], b)...)
    end
end

which is a generic version of the function suggested by @lmiq and I used splatting with map (suggestion found here: Work around splatting to avoid unecessary allocations) and type declaration (suggestion found here: Splatting arguments causes ~30x slow down) to avoid allocations.

An idea of the performance with a simple addition:

N = 10000;
a = ones(N); b = rand(N); c = rand(N);
w = collect(1:N)[rand(N) .< 0.5];

@btime set_awfb!(+, $a, $w, $b, $c)
  6.540 μs (0 allocations: 0 bytes)

@btime for i in $w
           @inbounds $a[i] = $b[i] + $c[i]
       end
  5.402 μs (0 allocations: 0 bytes)

@btime $a[$w] .= $b[$w] .+ $c[$w];
  17.878 μs (4 allocations: 78.03 KiB)

So still slower, but a good improvement compared to broadcasting!