矢量化时,Tuple的Vector如何分配比较快?

using BSON: @load
using BenchmarkTools

@load "zvec_δvec.bson" zvec δvec

const restenergy = 0.511e6            # [eV]

nturns = 10001

struct Par
    v1
    r
    ϕs
    ϕ2s
    h1
    h
    circum
    centerenergy
    αc
end
Base.broadcastable(x::Par) = Ref(x)

function revolution(z, δ, p::Par)
    δ = δ + p.v1 * (sin(p.ϕs - 2 * p.h1 * π * z / p.circum) - sin(p.ϕs) + p.r * sin(p.ϕ2s - 2 * p.h1 * p.h * π * z / p.circum) - p.r * sin(p.ϕ2s)) / p.centerenergy / p.circum
    η = p.αc - 1 / (p.centerenergy * (1 + δ) / restenergy)^2
    z = z - η * δ
    z, δ
end

function main!(zvec, δvec, nturns, p::Par)
    npart = size(zvec, 1)
    zmat = zeros(npart, nturns)
    δmat = zeros(npart, nturns)

    for i = 1:nturns
        zvec, δvec = revolution.(zvec, δvec, p)
        zmat[:, i] .= zvec
        δmat[:, i] .= δvec
    end
end

p = Par(3.6395053705870048e+06,0.1801760487622639,2.1575815005097385,6.0620746573056303,756,3,1360.4,6e9,0.0000156)
@benchmark main!($zvec, $δvec, $nturns, $p)

这里的Base.broadcastable(x::Par) = Ref(x),我明明用在自己的包里,且能成功阻止它参与广播,这里出现毛病又是为啥呢?

复现代码不够,缺少这行代码导入的变量

@load "zvec_δvec.bson" zvec δvec

可以试试zvec=zeros(1000), δvec = zeros(1000)吗?
这里具体数值不重要的


目前来看,如果在终端将struct给定义了,并且也用了Base.broadcastable(x::Par) = Ref(x),是没问题的。

在文件中想一口气跑完,就会出错。

抱歉,是我看提示看得不够仔细。

这个广播错误不是struct的问题。是在这一步中:

zvec, δvec = revolution.(zvec, δvec, p)

右侧返回的是Vector{Tuple},这里zvec, δvec实际上只能拿到前两个Tuple

julia> a, b = [1,2,3,4,5]
5-element Vector{Int64}:
 1
 2
 3
 4
 5

julia> a
1

julia> b
2

涨了点见识呢,以前没注意过这个特性。

标题已经改为合适的了。