问题:我有一个新类型type MyFloat; x::Float64 ; end
。我想在deepcopy
上执行Vector{MyFloat}
。在Ubuntu 16.04上使用Julia v0.5.0,该操作比等效长度deepcopy
上的Vector{Float64}
调用慢大约150倍。是否可以加快deepcopy
上的Vector{MyFloat}
?
代码段:使用以下代码片段可以看到150倍减速,该代码段可以粘贴到REPL:
#Just my own floating point type
type MyFloat
x::Float64
end
#This function performs N deepcopy operations on a Vector{MyFloat} of length J
function f1(J::Int, N::Int)
v = MyFloat.(rand(J))
x = [ deepcopy(v) for n = 1:N ]
end
#The same as f1, but on Vector{Float64} instead of Vector{MyFloat}
function f2(J::Int, N::Int)
v = rand(J)
x = [ deepcopy(v) for n = 1:N ]
end
#Pre-compilation step
f1(2, 2);
f2(2, 2);
#Timings
@time f1(100, 15000);
@time f2(100, 15000);
在我的机器上产生:
julia> @time f1(100, 15000);
1.944410 seconds (4.61 M allocations: 167.888 MB, 7.72% gc time)
julia> @time f2(100, 15000);
0.013513 seconds (45.01 k allocations: 19.113 MB, 78.80% gc time)
查看答案here,我可以通过为copy
定义自己的MyFloat
方法来加快速度。我尝试过这样的事情:
Base.deepcopy(x::MyFloat)::MyFloat = MyFloat(x.x);
Base.deepcopy(v::Vector{MyFloat})::Vector{MyFloat} = [ MyFloat(y.x) for y in v ]
Base.copy(x::MyFloat)::MyFloat = MyFloat(x.x)
Base.copy(v::Vector{MyFloat})::Vector{MyFloat} = [ MyFloat(y.x) for y in v ]
但这并没有任何区别。
最后注意事项:a = MyFloat.([1.0, 2.0])
,我可以使用b = copy(a)
并且没有速度惩罚。这很好,只要我小心谨慎地执行b[1] = MyFloat(3.0)
之类的操作(这将修改b
而不是a
)。但如果我草率并且不小心写了b[1].x = 3.0
,那么这将修改a
和b
。
顺便说一句,完全有可能我对copy
和deepcopy
之间的差异没有深刻的理解......我已经阅读了this很棒的博文(谢谢@ChrisRackauckas),但我对更深层次的情况肯定有点模糊。
答案 0 :(得分:1)
Try changing type MyFloat
in the definition to immutable MyFloat
or struct MyFloat
(the keyword changed in 0.6). This makes the times almost equal.
As @Gnimuc mentioned, a mutable, which is not a bitstype, makes Julia keep track of a lot of other stuff. See here and in the comments.