Julia 朱莉娅-有没有办法让这个就地赋值函数看起来更好
考虑以下代码摘录:Julia 朱莉娅-有没有办法让这个就地赋值函数看起来更好,julia,allocation,Julia,Allocation,考虑以下代码摘录: q = zeros(5,5); x = rand(5,5); function testFunc!(n, q, x) for i = 1:n q .= x.^2; end end 我初始化q,并通过就地分配功能更新q中的值。无论我如何选择n,分配的数量都是恒定的,因为我没有创建任何新的内容 但是,有没有一种方法可以编写一个名为testFunc2的函数,如下所示: q = zeros(5,5) x = rand(5,5); q = testFu
q = zeros(5,5);
x = rand(5,5);
function testFunc!(n, q, x)
for i = 1:n
q .= x.^2;
end
end
我初始化q
,并通过就地分配功能更新q
中的值。无论我如何选择n
,分配的数量都是恒定的,因为我没有创建任何新的内容
但是,有没有一种方法可以编写一个名为testFunc2
的函数,如下所示:
q = zeros(5,5)
x = rand(5,5);
q = testFunc2(n, x)
macro wrap(ex)
outputs = ex.args[1].args
ex.args[2].args[1] = Symbol(ex.args[2].args[1], "!")
append!(ex.args[2].args, outputs)
esc(ex)
end
这样,内存分配对n
是不变的
我知道这看起来很傻,但在我的实际代码中,我有许多类似于
q
的变量,我有一个循环,每次迭代都会更新它们。我不希望代码占用过多的内存。如果我编写一个类似于testFunc2(n,x,q1,q2,q3,q4)
的函数,它的语法看起来会非常麻烦。因此,我希望能够拥有q1,q2,q3,q4=testFunc2(n,x)
,而不必担心内存问题 我不确定q1,q2,q3,q4=testFunc2(n,x)
看起来是否比testFunc2好得多!(n,x,q1,q2,q3,q4)
,但您可以使用以下宏执行这种类型的转换:
q = zeros(5,5)
x = rand(5,5);
q = testFunc2(n, x)
macro wrap(ex)
outputs = ex.args[1].args
ex.args[2].args[1] = Symbol(ex.args[2].args[1], "!")
append!(ex.args[2].args, outputs)
esc(ex)
end
扩大
@wrap q1, q2, q3, q4 = testFunc2(n, x)
进入
如果我理解正确,最简单的方法是使用闭包:
let
q1 = similar(q)
q2 = similar(q)
global function testFunc2(n, x)
for i = 1:n
q1 .= x.^2
q2 .= x.^2
end
return q1, q2
end
end
julia> @btime testFunc2(10, $x)
786.000 ns (0 allocations: 0 bytes)
julia> @btime testFunc2(100, $x)
7.476 μs (0 allocations: 0 bytes)
正如@Liso在下面的评论中指出的,如果我们不尝试在调用之间共享相同的内存,那么应该返回拷贝,例如返回拷贝(q1),拷贝(q2)
,而不是返回q1,q2
,那么我们仍然会得到恒定的内存分配:
@btime testFunc2(10, $x)
821.684 ns (3 allocations: 704 bytes)
@btime testFunc2(100, $x)
7.326 μs (3 allocations: 704 bytes)
无论如何,选择哪种方法取决于相应的用例,这是一个更灵活的选择 来自多个调用的结果共享相同的内存:
r1=testFunc2(10,零(5,5));println(r1[1][1]);r2=testFunc2(10,一(5,5));println(r1[1][1])
->0.01.0
这是我想要的吗?@Liso这就是我为什么写“如果我理解正确”;),我的想法只是为了说明闭包的概念。我已经更新了我的答案。很好!:)如果它真的是为了好看,那么可能类似于testFunc3!(n,x,q…)
也有帮助。