Julia: Array of ones: add one to zero or repeat?

Viewed 78

I have a concrete Array and want to efficiently construct a similar array of the same dimensions filled with ones. What would be the recommended approach?

Here's a random array to work with:

julia> A = rand(0:1, 10, 5)
10×5 Matrix{Int64}:

or A = rand(0:1., 10, 5) (with a dot on 0. and/or 1.) for a random matrix of floats.

Two approaches are very natural. I could do this:

julia> zero(A) .+ 1
5×10 Matrix{Int64}:

Or I could do it this way:

julia> repeat(ones(size(A)[2])', outer = size(A)[1])
5×10 Matrix{Float64}:

The first approach is more elegant. The second approach feels more clunky and prone to error (accidentally exchanging [1] and [2]), but at the same time it doesn't involve the addition operation and so possibly involves fewer allocations (or maybe not because the compiler is super smart Edit: quick benchmark below suggests the compiler is super smart).

And of course there may be another, better approach.

using BenchmarkTools
A = rand(0:1, 1000, 1000)

@btime zero(A) .+ 1
## 1.609 ms (6 allocations: 15.26 MiB)

@btime repeat(ones(size(A)[2])', outer = size(A)[1])
## 3.032 ms (10 allocations: 7.64 MiB)

Edit 2: Follow-up onBogumił's answer

The following method for a unit-array J, defined for convenience, is efficient:

function J(A::AbstractArray{T,N}) where {T,N}
    ones(T, size(A))
end
J(A)
@btime J(A)
## 789.929 μs (2 allocations: 7.63 MiB)
1 Answers

What about:

ones(Int, size(A))

or

fill(1, size(A))
Related