我有一个数组a,我需要浅层复制到一个数组b.我应该用吗?
b = collect(a)
Run Code Online (Sandbox Code Playgroud)
要么
b = Array(a)
Run Code Online (Sandbox Code Playgroud)
哪个是使用其中一个的差异?
copy是你在找什么:b = copy(a).
实际上,你也可以使用collect或Array完成这项工作,但有什么区别?在朱莉娅,有许多方便的帮助函数/宏可以用来挖掘幕后发生的事情.
@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
...
...
Run Code Online (Sandbox Code Playgroud)
这里的代码告诉我们collect将a(一个数组)视为一个迭代器,然后做一些迭代器操作的东西,而不只是一个浅的副本.Gallium.jl如果您想进一步深入研究代码,我建议使用Julia的调试包.Array(a)刚做了一个比一个更好的转换collect,但也没有必要.代码copy实际上是非常低级的:
copy{T<:Array}(a::T) = ccall(:jl_array_copy, Ref{T}, (Any,), a)
Run Code Online (Sandbox Code Playgroud)
另一个强大的工具是@code_xxx宏:
julia> @code_
@code_llvm @code_lowered @code_native @code_typed @code_warntype
Run Code Online (Sandbox Code Playgroud)
例如,您可以检索并比较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
}
Run Code Online (Sandbox Code Playgroud)
@code_llvm collect(a)将返回一堆代码,因为它不仅仅是一个简单的副本.我不熟悉LLVM,所以我说不出多少.