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…)
也有帮助。