当我不确定最终数组大小时,逐个元素构建 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].
有没有更快/更好的方法来做到这一点?
在 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)
| 归档时间: |
|
| 查看次数: |
42 次 |
| 最近记录: |