逐元素构建julia数组的有效方法

BoZ*_*haa 2 arrays julia

当我不确定最终数组大小时,逐个元素构建 Julia 数组的最佳方法是什么?在我的问题中,我在单个 for 循环中构建数组。

到目前为止,我已经发现我可以推入数组或索引到预先分配的数组中:

using BenchmarkTools

function push_to_array!(array, N)
    for i in 1:N
        # some computation
        push!(array, rand(Int64))
    end
end

function fill_array!(array, N)
    for i in 1:N
        # some computation
        array[i]=rand(Int64)
    end
end

N = 100_000_000 # unknown in the real problem

empty = Vector{Int64}()
preallocated = Vector{Int64}(undef, 2*N) # 2*N represents some upper bound on N

@btime push_to_array!(empty, N)
#  28.272 s (6 allocations: 0 bytes)
@btime fill_array!(preallocated, N)
#  2.449 s (0 allocations: 0 bytes)
Run Code Online (Sandbox Code Playgroud)

因此,填充预先分配的数组比推送快得多,但是,这有点麻烦,因为我需要使用correct_size = preallocated[1:N].

有没有更快/更好的方法来做到这一点?

Prz*_*fel 5

在 Julia 中,您有视图 - 无需修剪。简单地做:

correct_size = @view preallocated[1:1_000_000]
Run Code Online (Sandbox Code Playgroud)

或者

correct_size = view(preallocated, 1:1_000_000)
Run Code Online (Sandbox Code Playgroud)

现在这个操作非常便宜(顺便说一下,你没有正确地进行基准测试,因为它同时@time测量了编译时间和执行时间):

julia> using BenchmarkTools

julia> @btime correct_size = @view $preallocated[1:1_000_000];
  1.800 ns (0 allocations: 0 bytes)
Run Code Online (Sandbox Code Playgroud)

总之,制作一个view基本上是免费的。

最后,请注意,您可以只resize!使用数组(时间成本与 a 的情况相同@view):

resize!(preallocated, 1_000_000)
Run Code Online (Sandbox Code Playgroud)