Julia - 为什么使用宏 @info 会产生糟糕的 @code_warntype 性能?
Julia - Why using macro @info generates bad @code_warntype performance?
我想知道为什么使用@info 会产生糟糕的 err
变量性能:Any
。查看下一个 MWE:
function bad_performance()
@info "demo"
end
julia> @code_warntype bad_performance()
Variables
#self#::Core.Compiler.Const(test, false)
level::Base.CoreLogging.LogLevel
std_level::Base.CoreLogging.LogLevel
group::Symbol
_module::Module
logger::Union{Nothing, Base.CoreLogging.AbstractLogger}
id::Symbol
file::String
line::Int64
msg::String
err::Any
我应该改变什么来避免它,或者我应该忽略来自@code_warntype的这个红色警告?
注意:它还会为记录器变量生成黄色警告。
这是因为您可以创建自己的记录器并将其设置为当前记录器,它使用全局非常量变量。你可以用
更简单地看到同样的现象
julia> printstdout(str) = print(stdout, str)
printstdout (generic function with 1 method)
julia> @code_warntype optimize=true printstdout("hello")
Variables
#self#::Core.Const(printstdout)
str::String
Body::Union{Nothing, Int64}
1 ─ %1 = Main.print::Core.Const(print)
│ %2 = Main.stdout::Any
│ %3 = (isa)(%2, Cthulhu.TextWidthLimiter)::Bool
└── goto #3 if not %3
2 ─ %5 = π (%2, Cthulhu.TextWidthLimiter)
│ %6 = invoke %1(%5::Cthulhu.TextWidthLimiter, _2::String)::Union{Nothing, Int64}
└── goto #4
3 ─ %8 = Main.print(Main.stdout, str)::Union{Nothing, Int64}
└── goto #4
4 ┄ %10 = φ (#2 => %6, #3 => %8)::Union{Nothing, Int64}
└── return %10
虽然
julia> typeof(stdout)
Base.TTY
推断为Any
因为
julia> isconst(Base, :stdout)
false
必须是这样才能允许 redirect_stdout
。
好消息是糟糕的记录器推断仅在您实际记录时才有意义;如果它被包裹在一个不会被触发的 if
块中,对性能的影响通常是最小的。如果您发现它对您的情况很重要,请将 @info
放入一个单独的函数中,您可以从需要快速的函数中调用它。
我想知道为什么使用@info 会产生糟糕的 err
变量性能:Any
。查看下一个 MWE:
function bad_performance()
@info "demo"
end
julia> @code_warntype bad_performance()
Variables
#self#::Core.Compiler.Const(test, false)
level::Base.CoreLogging.LogLevel
std_level::Base.CoreLogging.LogLevel
group::Symbol
_module::Module
logger::Union{Nothing, Base.CoreLogging.AbstractLogger}
id::Symbol
file::String
line::Int64
msg::String
err::Any
我应该改变什么来避免它,或者我应该忽略来自@code_warntype的这个红色警告?
注意:它还会为记录器变量生成黄色警告。
这是因为您可以创建自己的记录器并将其设置为当前记录器,它使用全局非常量变量。你可以用
更简单地看到同样的现象julia> printstdout(str) = print(stdout, str)
printstdout (generic function with 1 method)
julia> @code_warntype optimize=true printstdout("hello")
Variables
#self#::Core.Const(printstdout)
str::String
Body::Union{Nothing, Int64}
1 ─ %1 = Main.print::Core.Const(print)
│ %2 = Main.stdout::Any
│ %3 = (isa)(%2, Cthulhu.TextWidthLimiter)::Bool
└── goto #3 if not %3
2 ─ %5 = π (%2, Cthulhu.TextWidthLimiter)
│ %6 = invoke %1(%5::Cthulhu.TextWidthLimiter, _2::String)::Union{Nothing, Int64}
└── goto #4
3 ─ %8 = Main.print(Main.stdout, str)::Union{Nothing, Int64}
└── goto #4
4 ┄ %10 = φ (#2 => %6, #3 => %8)::Union{Nothing, Int64}
└── return %10
虽然
julia> typeof(stdout)
Base.TTY
推断为Any
因为
julia> isconst(Base, :stdout)
false
必须是这样才能允许 redirect_stdout
。
好消息是糟糕的记录器推断仅在您实际记录时才有意义;如果它被包裹在一个不会被触发的 if
块中,对性能的影响通常是最小的。如果您发现它对您的情况很重要,请将 @info
放入一个单独的函数中,您可以从需要快速的函数中调用它。