gpt4 book ai didi

function - 快速匿名功能现在是自动的吗?

转载 作者:行者123 更新时间:2023-12-04 16:11:44 25 4
gpt4 key购买 nike

现在快速匿名函数是 julia 原生的,我是否仍然需要使用装饰器,或者它是自动实现的。另外,当我将一个函数作为参数传递给另一个函数时,我可以静态类型吗?我该怎么做才能提高运行速度。

最佳答案

FastAnonymous 绝对不再需要了。以下是您可以自己验证的方法:

julia> @noinline g(f, x) = f(x)  # prevent inlining so you know it's general
g (generic function with 1 method)

julia> h1(x) = g(identity, x)
h1 (generic function with 1 method)

julia> h2(x) = g(sin, x)
h2 (generic function with 1 method)

julia> @code_warntype h1(1)
Variables
#self#::Core.Compiler.Const(h1, false)
x::Int64

Body::Int64
1 ─ %1 = Main.g(Main.identity, x)::Int64
└── return %1

julia> @code_warntype h2(1)
Variables
#self#::Core.Compiler.Const(h2, false)
x::Int64

Body::Float64
1 ─ %1 = Main.g(Main.sin, x)::Float64
└── return %1

julia> h3(x) = g(z->"I'm a string", x)
h3 (generic function with 1 method)

julia> @code_warntype h3(1)
Variables
#self#::Core.Compiler.Const(h3, false)
x::Int64
#9::getfield(Main, Symbol("##9#10"))

Body::String
1 ─ (#9 = %new(Main.:(##9#10)))
│ %2 = #9::Core.Compiler.Const(getfield(Main, Symbol("##9#10"))(), false)
│ %3 = Main.g(%2, x)::Core.Compiler.Const("I'm a string", false)
└── return %3

在任何情况下,Julia 都知道返回类型,这就要求它“理解”你的函数参数在做什么。此外:

julia> m = first(methods(g))
g(f, x) in Main at REPL[1]:1

julia> m.specializations
Core.TypeMapEntry(Core.TypeMapEntry(Core.TypeMapEntry(nothing, Tuple{typeof(g),typeof(identity),Int64}, nothing, svec(), 1, -1, MethodInstance for g(::typeof(identity), ::Int64), true, true, false), Tuple{typeof(g),typeof(sin),Int64}, nothing, svec(), 1, -1, MethodInstance for g(::typeof(sin), ::Int64), true, true, false), Tuple{typeof(g),getfield(Main, Symbol("##9#10")),Int64}, nothing, svec(), 1, -1, MethodInstance for g(::getfield(Main, Symbol("##9#10")), ::Int64), true, true, false)

这有点难读,但如果你仔细看,你会发现 g 已经为 3 个输入编译:

  • 元组{typeof(identity), Int64}
  • 元组{typeof(sin), Int64}
  • 元组{getfield(Main, Symbol("##9#10")),Int64}

(编译后的版本也将 g 本身作为一个额外的参数,原因与关键字参数处理的内部实现有关,但现在让我们忽略它。)最后一个一个是为实现匿名函数的类型生成的名称。这表明每个函数都有自己的类型,这就是为什么将函数作为参数传递很快的原因。

对于专家来说,还有一个因素可以发挥作用:因为类型推断受制于无法解决的 halting problem ,在某些情况下,推理会决定这一切都变得过于复杂并“过早”中止。在这种情况下(相对罕见),它可以帮助强制编译器专门针对特定参数。在我们的示例中,这意味着将 g 声明为

@noinline g(f::F, x) where F = f(x)

而不是

@noinline g(f, x) = f(x)

::F 通常是不必要的并且看起来毫无用处,但您可以将其用作编译器提示来增加用于推断结果的工作量。我不建议默认这样做(这会使您的代码更难阅读),但如果您发现奇怪的性能问题,这是一回事。

关于function - 快速匿名功能现在是自动的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57740735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com