微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Julia 中绑定函数参数

如何解决在 Julia 中绑定函数参数

Julia 是否提供类似于 C++ 中的 std::bind 的东西?我希望按照以下方式做一些事情:

function add(x,y)
  return x + y
end


add45 = bind(add,4,5)
add2 = bind(add,_1,2)
add3 = bind(add,3,_2)

如果这是可能的,它会产生任何性能开销吗?

解决方法

如回答 here,您可以使用 Julia 中的高阶函数获得此行为。

关于性能。应该没有开销。实际上,在这种情况下,编译器应该内联所有内容,甚至执行常量传播(以便代码实际上可以更快)。在另一个答案 here 中使用 const 只是因为我们在全局范围内工作。如果所有这些都将在函数中使用,则不需要 const(因为采用此参数的函数将被正确编译),因此在下面的示例中我不使用 const

让我举例说明 Base.Fix1 和您的 add 函数:

julia> using BenchmarkTools

julia> function add(x,y)
         return x + y
       end
add (generic function with 1 method)

julia> add2 = Base.Fix1(add,10)
(::Base.Fix1{typeof(add),Int64}) (generic function with 1 method)

julia> y = 1:10^6;

julia> @btime add.(10,$y);
  1.187 ms (2 allocations: 7.63 MiB)

julia> @btime $add2.($y);
  1.189 ms (2 allocations: 7.63 MiB)

请注意,我没有将 add2 定义为 const,而且由于我们处于全局范围内,因此我需要在它前面加上 $ 以将其值插入到基准测试套件中。

如果我不这样做,你会得到:

julia> @btime add2.($y);
  1.187 ms (6 allocations: 7.63 MiB)

本质上是相同的时间和内存使用,但分配 6 次而不是 2 次,因为在这种情况下 add2 是类型不稳定的全局变量。

我在 DataFrames.jl 上工作,在那里使用我们在这里讨论的模式非常有用。我只举一个例子:

julia> using DataFrames

julia> df = DataFrame(x = 1:5)
5×1 DataFrame
 Row │ x
     │ Int64
─────┼───────
   1 │     1
   2 │     2
   3 │     3
   4 │     4
   5 │     5

julia> filter(:x => <(2.5),df)
2×1 DataFrame
 Row │ x
     │ Int64
─────┼───────
   1 │     1
   2 │     2

该操作的作用是选取列 :x 中的值小于 2.5 的行。这里要理解的关键是 <(2.5) 的作用。它是:

julia> <(2.5)
(::Base.Fix2{typeof(<),Float64}) (generic function with 1 method)

如您所见,它与我们定义 x -> x < 2.5 函数时获得的结果类似(本质上是修复 < 函数的第二个参数,如 Julia < 是只是一个两个参数的函数)。像上面的 <(2.5) 这样的快捷方式在 Julia 中默认定义为几个常见的比较运算符。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。