结论放在前面:
- 复杂的struct必须使用deepcopy
- 对于复杂结构(array of struct等),deepcopy()可能不如new一个新的把值导进去快
第二个结论是我在其他项目上测试后的结果,结论如上图,这里没有测试。
以下是第一个结论的测试
一个很有用的帖子:https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648
需要注意的是,mutable struct需要使用deepcopy
这是我的测试代码
using Base.Threads
using LinearAlgebra
# check the change of variables
mutable struct Test
a::Int64
b::Int64
end
function test()
n = 3
println("Threads", Threads.nthreads())
println("test 1: struct, with !")
test0 = [Test(0, 0)]
sum_test1 = Vector{Int64}(undef, n)
@threads for i in 1:n
test1 = copy(test0)
test = test_operate(test2)
sum_test1[i] = test.a
end
for i in 1:n
println(sum_test1[i])
end
println("test 2: Vector, with !")
test0 = [0, 0]
sum_test2 = Vector{Int64}(undef, n)
@threads for i in 1:n
test2 = copy(test0)
test = test_operate(test2)
sum_test2[i] = test[1]
end
for i in 1:n
println(sum_test2[i])
end
end
function test_operate(case::Union{Vector{Test},Vector{Int64}})
if case isa Vector{Test}
case = case[1]
end
case1 = test_add!(case)
return case1
end
function test_add!(case::Test)
case.a += 1
return case
end
function test_add!(case::Vector{Int64})
case[1] += 1
return case
end
test()
以下为我的output:
Threads2
test 1: struct, with !
1
2
3
test 2: Vector, with !
1
1
1
对于Vector{Float}这样的变量,copy 就足够了。但是Vector{struct}这样的形式,需要使用deepcopy,这与是否是函数无关。事实上,如果copy(struct)是会报错的,而copy(Vector{struct})并没有报错,这给我带来了一些误解。
我困扰于,把threads换成spawn会出现非常奇怪的结果。
以及带有!的函数事实上并不总是改变传入变量。这实际上是一种命名规范,详细可见https://docs.juliacn.com/latest/manual/style-guide/
此处我还需要额外测试。