gpt4 book ai didi

julia - 以复合类型添加所有数组的高效而简洁的方法?

转载 作者:行者123 更新时间:2023-12-01 07:28:47 25 4
gpt4 key购买 nike

我想出了两种方法来将所有数组添加到一对复合类型中。第一种方式 (add_structs_1) 需要 4 秒才能运行,第二种方式 (add_structs_2) 需要 0.15 秒。但是第二种方式需要更多的代码……我必须明确提及复合类型中的每个字段。有没有办法在不显式列出每个字段的情况下提高 add_structs_2 的效率?

type SampleStruct
a::Vector{Float64}
k::Matrix{Float64}
e_axis::Vector{Float64}
e_dev::Vector{Float64}
e_scale::Vector{Float64}
end

function add_structs_1(tgt::SampleStruct, src::SampleStruct)
for n in names(SampleStruct)
for i in 1:length(tgt.(n))
tgt.(n)[i] += src.(n)[i]
end
end
end

function add_structs_2(tgt::SampleStruct, src::SampleStruct)
for i in 1:length(tgt.a)
tgt.a[i] += src.a[i]
end

for i in 1:length(tgt.k)
tgt.k[i] += src.k[i]
end

for i in 1:length(tgt.e_axis)
tgt.e_axis[i] += src.e_axis[i]
end

for i in 1:length(tgt.e_dev)
tgt.e_dev[i] += src.e_dev[i]
end

for i in 1:length(tgt.e_scale)
tgt.e_scale[i] += src.e_scale[i]
end
end

function time_add_structs(f::Function)
src = SampleStruct(ones(3), ones(3,3), [1.], [1.], [1.])
tgt = SampleStruct(ones(3), ones(3,3), [1.], [1.], [1.])

@time for i in 1:1000000
f(tgt, src)
end
end

time_add_structs(add_structs_1)
time_add_structs(add_structs_1)

time_add_structs(add_structs_2)
time_add_structs(add_structs_2)

time_add_structs(add_structs_3)
time_add_structs(add_structs_3)

最佳答案

add_structs_1 的更有效的方法是使内部循环成为一个单独的函数,这允许编译器针对 SampleStruct 中的每种类型专门化该函数,并给出相当加速。

通过分析代码可以看出执行 names(SampleStruct) 的时间非常长,这应该在基准测试的每次迭代中完成,方法是在某个时间将其设置为全局常量得到了,函数现在看起来像:

function add_array(a::AbstractArray,b::AbstractArray)
for i in 1:length(a)
a[i] += b[i]
end
end
const names_in_struct = names(SampleStruct)
function add_structs_3(tgt::SampleStruct, src::SampleStruct)
for n in names_in_struct
add_array(tgt.(n),src.(n))
end
end

该函数现在是 add_structs_2

的四分之一

元编程方法更复杂,但提供与 add_structs_2 相同的性能

ex = Any[]
for n in names(SampleStruct)
t = Expr(:.,:tgt, QuoteNode(n))
s = Expr(:.,:src, QuoteNode(n))
e=quote
for i in 1:length($t)
$t[i] += $s[i]
end
end
push!(ex,e)
end
eval(quote function add_structs_4(tgt::SampleStruct, src::SampleStruct)
$(Expr(:block,ex...))
end
end)

关于julia - 以复合类型添加所有数组的高效而简洁的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29856921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com