如果我们运行:
@code_warntype deepcopy(rand(2))
Run Code Online (Sandbox Code Playgroud)
在Julia REPL中,输出包含Body表达式中的标记值.具体来说,两个Any在结尾:
Body:
begin # deepcopy.jl, line 8:
GenSym(0) = (Base.Array)(Base.Any,32)::Array{Any,1}
return (Base.deepcopy_internal)(x::Array{Float64,1},$(Expr(:new, :((top(getfield))(Base,:ObjectIdDict)::Type{ObjectIdDict}), GenSym(0))))::Any
end::Any
Run Code Online (Sandbox Code Playgroud)
我从这个问题中了解到,如果主要关注的是类型不稳定,我们通常不需要担心Body表达式中的标记值.相反,我的问题是:
为什么Base生成任何标记值的相当简单的函数@code_warntype?我确信有充分的理由,但我是新解释的输出@code_warntype,并且在从官方文档中理解Body表达式的讨论时遇到了一些麻烦.
这是类型推断无法确定函数的返回类型的情况的示例.(注意::Any返回值!)这是一个问题,不是因为类型不稳定而计算本身会变慢,而是因为无法推断返回类型,因此使用返回类型的未来计算将受到类型不稳定的影响.
您可以通过查看以下分配来查看此效果:
julia> function f()
y = rand(10)
@time y[1] + y[10]
z = deepcopy(y)
@time z[1] + z[10]
end
f (generic function with 1 method)
julia> f(); # ignore output here on first compile
julia> f();
0.000000 seconds
0.000002 seconds (3 allocations: 48 bytes)
Run Code Online (Sandbox Code Playgroud)
请注意,第二个操作需要分配并需要时间,因为涉及拆箱和动态分派.
在目前的每晚构建0.5(可能会在几个月内发布),这已得到修复.从而
julia> @code_warntype deepcopy(rand(2))
Variables:
#self#::Base.#deepcopy
x::Array{Float64,1}
Body:
begin # deepcopy.jl, line 8:
# meta: location dict.jl Type # dict.jl, line 338:
SSAValue(1) = (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Any,1)::Type{Array{Any,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Any,1},0,32,0)::Array{Any,1}
# meta: pop location
return (Core.typeassert)((Base.deepcopy_internal)(x::Array{Float64,1},$(Expr(:new, :(Base.ObjectIdDict), SSAValue(1))))::Any,Array{Float64,1})::Array{Float64,1}
end::Array{Float64,1}
Run Code Online (Sandbox Code Playgroud)
没有类型不稳定,和
julia> f()
0.000000 seconds
0.000000 seconds
Run Code Online (Sandbox Code Playgroud)
没有动态调度和没有分配.
| 归档时间: |
|
| 查看次数: |
335 次 |
| 最近记录: |