将参数传递给函数而不在JULIA-LANG中复制它们

zwl*_*yer 3 parameter-passing julia

假设我需要创建一个巨大的数组并在我的程序中使用它在另一个函数中.我想这样做,而不是每次使用它时都复制这个数组.我知道如果我只是将它们作为参数给出,Julia有一个共享调用机制,它不会复制参数.但是,如果我按照以下方式执行某些操作,它是否仍然能够在循环中每次都不创建副本的情况下运行?:

function main()
    huge_arr = ones(Float32,20000,30000)
    another_arr = rand(4,5)
    coupled_var = (huge_arr,another_arr)
    for i=1:100  
        target_function(coupled_var)
    end
end

function target_function(x)
   my_first_var = x[1]
   my_second_var = x[2] 
   # some operations here 
end
Run Code Online (Sandbox Code Playgroud)

Pic*_*ent 11

您正在操作可变对象(声明为mutable struct Array{...} ...)的数组,因此通过引用语义传递.

function target_function(x)
   my_first_var = x[1]        # x[1],x[2] are _mutable_ objects 
   my_second_var = x[2]       # -> this only create a new binding (no copy)
   # some operations here 
end
Run Code Online (Sandbox Code Playgroud)

您可以使用pointer_from_objref检查my_first_varx[1]指向同一对象.

例子:

function foo(x) 
   y = x
   println("Check ptr $(pointer_from_objref(x) == pointer_from_objref(y)) x:$(pointer_from_objref(x)) y:$(pointer_from_objref(y))")
end
Run Code Online (Sandbox Code Playgroud)

然后尝试:

x=4.5
foo(x)
Check ptr false x:Ptr{Void} @0x00007f25a28a2850 y:Ptr{Void} @0x00007f25a28a2860
Run Code Online (Sandbox Code Playgroud)

- >对于a Float64,y = x执行深层复制

x=rand(5)
foo(x)
Check ptr true x:Ptr{Void} @0x00007f25a284a410 y:Ptr{Void} @0x00007f25a284a410
Run Code Online (Sandbox Code Playgroud)

- >对于数组,y = x执行拷贝(共享相同的内存地址)

注意:在您target_function处理使用组件级操作时,例如my_first_var .*= 2因为某些 操作my_first_var *= 2 会创建一个新变量.

例如:

julia> pointer_from_objref(x)
Ptr{Void} @0x00007f25a043f890   <-
                                  |
julia> x *= 2                     |
5-element Array{Float64,1}:
 3.81254
 3.60607
 2.86026
 1.94396
 2.91994                        different memory
                                  |
julia> pointer_from_objref(x)     |
Ptr{Void} @0x00007f25a0afa210  <--|
                                  |
julia> x .*= 2
5-element Array{Float64,1}:
 7.62507
 7.21214
 5.72052
 3.88793
 5.83987                     same memory
                                 |
julia> pointer_from_objref(x)    |
Ptr{Void} @0x00007f25a0afa210 <--|
Run Code Online (Sandbox Code Playgroud)