Julia:连接生成器内容和另一个向量的最高效方法

问题描述 投票:0回答:1

我想生成一个数组,并且我知道我希望它以一组固定的值结尾,比如

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
arrays performance julia
1个回答
0
投票

使用 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>

是否有一个声明性数组构建器语法看起来更像我最初编写的,但执行起来像这个循环代码?

循环显然更容易阅读,这导致人们以这种风格编写它。我希望有一个类似的可读且高性能的替代方案来呈现。谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.