【发布时间】:2017-09-24 17:42:50
【问题描述】:
考虑以下示例:
module structs
mutable struct testStruct
x::Array{Int64,2}
end
end
function innerFunc(s::structs.testStruct)
s.x[1:2] .= s.x[3:4]
end
function structTest!(s::structs.testStruct, n)
for i = 1:n
innerFunc(s)
end
println(s.x)
end
随着我增加n,内存分配也会增加。我认为这是因为在每次迭代中,我都会为s.x[3:4] 创建一个分配。我可以通过使用循环来避免这种情况:
function innerFunc(s::structs.testStruct)
for i = 1:2
s.x[i] .= s.x[i+2]
end
end
function structTest!(s::structs.testStruct, n)
for i = 1:n
innerFunc(s)
end
println(s.x)
end
但是,我不喜欢循环,因为语法很麻烦。有没有办法避免它?在每次迭代中,我想修改s.x 的第一个和第二个元素而不增加内存分配,因为我增加了n,因为我没有创建任何新内容。
更新:为了响应 DNF,我尝试使用@view:
module structs
mutable struct testStruct
x::Array{Int64,2}
end
end
function innerfunc!(s::structs.testStruct)
s.x[1:2] .= view(s.x, 3:4)
end
function structTest!(s::structs.testStruct, n)
for i = 1:n
innerfunc!(s)
end
println(s.x)
end
这是我得到的:
@time structTest!(structs.testStruct([1 2 3 4]),33)
0.000112 seconds (202 allocations: 7.938 KiB)
@time structTest!(structs.testStruct([1 2 3 4]),330)
0.000126 seconds (1.69 k allocations: 68.266 KiB)
我希望分配对n 保持不变。
【问题讨论】:
-
我不确定您为什么认为要避免循环?这是直截了当的解决方案,您为什么认为它很麻烦?
-
我不喜欢这种语法。使用矢量化操作(或类似矢量化的操作)使代码看起来更直观。
-
视图当前分配了一点点,但这是将在 1.x 中解决的优化问题之一。一般来说,我不会担心它,因为它很小,而且迟早会消失。
标签: performance julia allocation