如何在调用递归内部函数时避免创建FSharpFunc的新实例?

时间:2013-12-16 04:52:18

标签: performance recursion f# inline

样品:

let inline ReadState() = 

    let rec f (w : SpinWait) = 
        if (...) then
            w.SpinOnce()
            f(w)
        else
            result 

    f (new SpinWait())

使用ILSpy我注意到ReadState()每次调用时都会创建FSharpFunc的新实例

new Memory@f222().Invoke()  // Memory@f222 implement FSharpFunc

如何避免它?

如果f not inner fun然后no instance created,但我需要另一个命名函数:

let rec InternalReadState(w : SpinWait) = .... 

let ReadState() = InternalReadState(new SpinWait())

不是很漂亮:(

1 个答案:

答案 0 :(得分:2)

在我看来,你有几个选择,但你可能对它们中的任何一个都不满意。最简单的方法是删除inline,然后将()参数移到嵌套函数之后:

let ReadState = 

    let rec f (w : SpinWait) = 
        if (...) then
            w.SpinOnce()
            f(w)
        else
            result 

    fun () -> f (new SpinWait())

您需要在此处删除inline,因为它只能应用于语法功能。

另一种选择是创建另一个命名函数,如您所知。如果您担心使用不需要的命名函数污染您的范围,那么有一些选项可以减轻这种情况。您可以使用签名文件仅公开ReadState函数,或者您可以使用private修饰符将其设置为您所在范围之外的私有文件:

module MyStuff =
    let rec private f (w:SpinWait) = ...
    let inline ReadState() = f (new SpinWait())