首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我们什么时候应该使用FSharpFunc.Adapt?

我们什么时候应该使用FSharpFunc.Adapt?
EN

Stack Overflow用户
提问于 2011-03-17 14:58:43
回答 1查看 544关注 0票数 19

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

代码语言:javascript
复制
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,还是只在很少的时候使用?

耽误您时间,实在对不起。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-03-17 20:33:18

这很有趣!我没有任何官方信息(我在任何地方都没有看到这方面的文档),但是这里有一些关于Adapt函数如何工作的想法。

mapi这样的函数采用简单的函数形式,这意味着参数的类型被编译成类似FSharpFunc<int, FSharpFunc<T, R>>的类型。然而,许多函数实际上被直接编译为具有两个参数的函数,因此实际的值通常是从FSharpFunc<int, FSharpFunc<T, R>>继承的FSharpFunc<int, T, R>

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

代码语言:javascript
复制
FSharpFunc<int, string>.InvokeFast<a>(f, 1, "a");

如果您使用Reflector查看InvokeFast函数,您将看到它测试该函数是否被编译为优化版本(f :? FSharpFunc<int, T, R>)。如果是,则直接调用Invoke(1, "a"),如果不是,则需要进行两次Invoke(1).Invoke("a")调用。

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

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

因此,总结一下,如果你调用一个作为参数传递的函数,而这个函数需要多次接受超过1个参数,那么Adapt可以提高性能。与任何优化一样,我不会盲目地使用它,但在调优性能时,这是一件有趣的事情!

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

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5335858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档