gpt4 book ai didi

f# - 我们什么时候应该使用 FSharpFunc.Adapt?

转载 作者:行者123 更新时间:2023-12-03 14:14:33 25 4
gpt4 key购买 nike

查看 FSharp.Core 和 PowerPack 中的源代码,我看到许多接受具有两个或多个参数的函数的高阶函数使用 FSharpFunc.Adapt .例如:

let mapi f (arr: ResizeArray<_>) =
let f = FSharpFunc<_,_,_>.Adapt(f)
let len = length arr
let res = new ResizeArray<_>(len)
for i = 0 to len - 1 do
res.Add(f.Invoke(i, arr.[i]))
res
FSharpFunc.Adapt 上的文档相当薄。这是我们应该在任何时候使用具有类似签名的高阶函数的一般最佳实践吗?只有多次调用传入的函数?有多少优化?我们应该使用 Adapt我们可以在任何地方,还是很少?

谢谢你的时间。

最佳答案

这很有趣!我没有任何官方信息(我也没有在任何地方看到这个记录),但这里有一些关于 Adapt 的想法功能可能会起作用。
mapi 等函数采用函数的柯里化(Currying)形式,这意味着参数的类型被编译为类似 FSharpFunc<int, FSharpFunc<T, R>> .但是,许多函数实际上是直接编译为两个参数的函数,因此实际值通常为 FSharpFunc<int, T, R>继承自 FSharpFunc<int, FSharpFunc<T, R>> .

如果您调用此函数(例如 f 1 "a" ),F# 编译器会生成如下内容:

FSharpFunc<int, string>.InvokeFast<a>(f, 1, "a");

如果您查看 InvokeFast使用反射器的函数,你会看到它测试了函数是否被编译为优化版本( f :? FSharpFunc<int, T, R> )。如果是,则直接调用 Invoke(1, "a")如果没有,则需要调用两个电话 Invoke(1).Invoke("a") .

每次调用作为参数传递的函数时都会执行此检查(执行检查然后使用优化调用可能更快,因为这更常见)。

什么 Adapt函数所做的是将任何函数转换为 FSharpFunc<T1, T2, R> (如果该函数未优化,它会为其创建一个包装器,但大多数情况下并非如此)。对适配函数的调用会更快,因为它们不需要每次都进行动态检查(检查只在 Adapt 内进行一次)。

所以,总结是 Adapt如果您调用作为参数传递的函数多次使用超过 1 个参数,则可以提高性能。与任何优化一样,我不会盲目使用它,但在调整性能时要注意这是一件有趣的事情!

(顺便说一句:感谢一个非常有趣的问题,我不知道编译器会这样做:-))

关于f# - 我们什么时候应该使用 FSharpFunc.Adapt?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5335858/

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