具有多个功能输出的Julia内存重用

时间:2017-01-26 23:07:08

标签: memory-management julia

您可以按如下方式重用数组内存

> a=[1,2,3];b=a;a=[1,2,3];is(a,b)
false

> a=[1,2,3];b=a;a.=[1,2,3];is(a,b)
true

在我分配整个阵列时,这是唯一必要的。分配子集时,无论是使用.=还是=,您都将始终使用现有数组。

当使用具有多个输出的函数时,我遇到了这个问题。例如:

> f = () -> ([1,2,3],[4,5,6]);
> a, = f()
([1,2,3],[4,5,6])

> a, .= f()
 ERROR: syntax: invalid identifier name ".="

> (a,) .= f()
ERROR: MethodError: no method matching broadcast!(::Base.#identity,::Tuple{Array{Int64,1}}, ::Tuple{Array{Int64,1},Array{Int64,1}})
Closest candidates are:
  broadcast!{nargs}(::Any, ::AbstractArray{T,N}, ::Any...) at broadcast.jl:169
  broadcast!(::Base.#identity, ::AbstractArray{T,N}, ::Number) at broadcast.jl:19
  broadcast!{T,S,N}(::Base.#identity, ::AbstractArray{T,N}, ::AbstractArray{S,N}) at broadcast.jl:23

有没有办法做到这一点,而不必在每次通话时丢弃a

1 个答案:

答案 0 :(得分:6)

a .= f()[1]

诀窍。但是,我应该注意,这确实避免为输出数组分配内存(也许是你的意图?);它仍然被分配,然后在将其内容复制到a后最终进行垃圾收集。唯一的方法是将a作为参数传递给f!的变异f变体。

我认为没有合适的语法来分配两个输出。您可以将f()的结果存储在临时(此存储不涉及复制,因为它只是对f()返回的内存进行别名):

tmp = f()
a .= tmp[1]
b .= tmp[2]