问题:,我有一种新型的type MyFloat; x::Float64 ; end。我想在deepcopy上执行Vector{MyFloat}。在Ubuntu16.04上使用JuliaV0.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)看看答案这里,听起来我可以通过为MyFloat定义自己的copy方法来加快速度。我试过这样的方法:
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之间的区别没有很深的理解。我读过这伟大的博客文章(谢谢@ChrisRackauckas),但我肯定对更深层次上正在发生的事情有些模糊。
发布于 2017-05-16 09:31:52
尝试将定义中的type MyFloat更改为immutable MyFloat或struct MyFloat (关键字在0.6中更改)。这使得时代几乎是平等的。
正如@Gnimuc所提到的,一个可变的,而不是一个小类型,使朱莉娅跟踪了许多其他的东西。请参阅这里和评论。
https://stackoverflow.com/questions/43952728
复制相似问题