我应该使用collect或Array来浅层复制Julia中的数组

时间:2017-04-03 13:34:13

标签: arrays copy julia

我有一个数组a,我需要浅层复制到数组b。 我应该使用

b = collect(a)

b = Array(a)

哪个是使用其中一个的差异?

2 个答案:

答案 0 :(得分:6)

copy正是您所寻找的:b = copy(a)

实际上,您也可以使用collectArray来完成这项工作,但有什么区别?在朱莉娅,有许多方便的帮助函数/宏可以用来挖掘幕后发生的事情。

@which@edit@less经常用于确定源代码中调用的方法:

julia> a = rand(3,3)
julia> @which collect(a)
collect(itr) at array.jl:273

julia> @which Array(a)
(::Type{T}){T}(arg) at sysimg.jl:53

julia> @less collect(a)
collect(itr) = _collect(1:1 #= Array =#, itr, iteratoreltype(itr), iteratorsize(itr))
...
...

julia> @less Array(a)
(::Type{T}){T}(arg) = convert(T, arg)::T
...
...

这里代码告诉collecta(一个数组)视为迭代器,然后做一些迭代器操作的东西,而不只是浅拷贝。如果您想进一步深入研究代码,我建议使用Julia的调试包Gallium.jlArray(a)刚刚进行了比collect更好的转换,但也没有必要。 copy的代码实际上非常低级:

copy{T<:Array}(a::T) = ccall(:jl_array_copy, Ref{T}, (Any,), a) 

另一个强大的工具是@code_xxx宏:

julia> @code_
@code_llvm     @code_lowered   @code_native    @code_typed     @code_warntype

例如,您可以检索并比较LLVM-IR代码以观察差异:

julia> @code_llvm Array(a)

define %jl_value_t* @julia_Type_73446(%jl_value_t*, %jl_value_t**, i32) #0 {
top:
  %3 = alloca %jl_value_t**, align 8
  store volatile %jl_value_t** %1, %jl_value_t*** %3, align 8
  %4 = load %jl_value_t*, %jl_value_t** %1, align 8
  ret %jl_value_t* %4
}

julia> @code_llvm copy(a)

define %jl_value_t* @julia_copy_73507(%jl_value_t*) #0 {
top:
  %1 = call %jl_value_t* inttoptr (i64 4478340144 to %jl_value_t* (%jl_value_t*)*)(%jl_value_t* %0)
  ret %jl_value_t* %1
}

@code_llvm collect(a)将返回一堆代码,因为它不仅仅是一个简单的副本。我不熟悉LLVM,所以我不能说太多。

答案 1 :(得分:3)

copy 是正确的!

help?> copy
search: copy copy! copysign deepcopy unsafe_copy! cospi complex Complex Complex64 Complex32 Complex128 CompositeException

  copy(x)

  Create a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an array
  produces a new array with identically-same elements as the original.