我想生成一个数组,并且我知道我希望它以一组固定的值结尾,比如
3,2,1
。
假设我想产生与此相同的结果:
julia> N = 10;
julia> [(i^2 for i in 1:N)..., 3, 2, 1]
13-element Vector{Int64}:
1
4
9
16
25
36
49
64
81
100
3
2
1
适用于非常长的 N(也可能适用于长后缀)。
我知道,一般来说,通过 vcat 构造数组比通过 splatting 构造数组更好。例如:
julia> let a = fill(0.0, 1000)
@btime [$a..., $10.0]
end;
34.250 μs (1002 allocations: 23.64 KiB)
julia> let a = fill(0.0, 1000)
@btime [$a; $10.0]
end;
685.833 ns (18 allocations: 8.36 KiB)
在这里泼溅发电机有惩罚吗?有更好的选择吗?
这是比较的基准:
julia> @btime [(i^2 for i in 1:$1000)..., 3, 2, 1];
52.541 μs (2477 allocations: 93.95 KiB)
当然我尝试了vcatting,但是生成器不是数组,所以它不收集其内容,它只是收集数组:
julia> [(i^2 for i in 1:10); 3; 2; 1]
4-element Vector{Any}:
Base.Generator{UnitRange{Int64}, var"#47#48"}(var"#47#48"(), 1:10)
3
2
1
使用 for 循环手动编写数组构建器操作速度更快,我想这并不奇怪。
julia> function make_array_321(N)
a = sizehint!(Int[], N + 3)
for i in 1:N
push!(a, i^2)
end
append!(a, (3,2,1))
return a
end
make_array_321 (generic function with 1 method)
julia> @btime make_array_321($1000);
3.234 μs (2 allocations: 8.00 KiB)
julia>
是否有一个声明性数组构建器语法看起来更像我最初编写的,但执行起来像这个循环代码?
循环显然更容易阅读,这导致人们以这种风格编写它。我希望有一个类似的可读且高性能的替代方案来呈现。谢谢!