You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

F#类内成员函数记忆化失效问题技术问询

F#类中记忆化失效问题的解决办法

你的问题根源在于类成员的定义方式:member this.MemoAddToOne = Memoize AddToOne是只读属性,每次访问该属性时都会重新执行Memoize AddToOne——也就是每次都会新建一个空的Dictionary,自然无法保留之前的缓存结果。而类外代码中Memoize仅被调用一次,对应的字典会持续存在,所以记忆化有效。

另外注意原代码里的fun c -是输入错误,正确写法是fun c ->。

修正方案1:将记忆化函数作为类字段初始化

把Memoize的调用放在类的字段定义中,这样类实例创建时仅执行一次Memoize,字典会绑定到实例上,持续保留缓存:

open System
open System.Collections.Generic

let Memoize f =
    let dict = Dictionary<_, _>()
    fun c ->
        let exists, value = dict.TryGetValue c
        match exists with
        | true -> value
        | _ ->
            let value = f c
            dict.Add(c, value)
            value

type MyClass() as this = 
    let rec AddToOne(x) = if x <= 1 then 1 else x + AddToOne(x-1)
    let rec AddToOneSkip(x) = if x <= 1 then 1 else x + AddToOneSkip(x-2)
    
    // 改为字段,实例化时仅执行一次Memoize
    let memoAddToOne = Memoize AddToOne
    let memoAddToOneSkip = Memoize AddToOneSkip
    
    // 成员属性返回预初始化的记忆化函数
    member this.MemoAddToOne = memoAddToOne
    member this.MemoAddToOneSkip = memoAddToOneSkip

[<EntryPoint>]
let main args = 
    let x = new MyClass()
    
    for i in 1..100000 do
        Console.WriteLine(x.MemoAddToOneSkip(i))

    for i in 1..100000 do
        Console.WriteLine(x.MemoAddToOne(i))
    
    0

修正方案2:懒加载记忆化函数(可选)

如果担心实例化时就创建字典浪费资源,可以用lazy实现延迟初始化,第一次调用时才创建字典:

type MyClass() as this = 
    let rec AddToOne(x) = if x <= 1 then 1 else x + AddToOne(x-1)
    let rec AddToOneSkip(x) = if x <= 1 then 1 else x + AddToOneSkip(x-2)
    
    // 懒加载,第一次访问时才执行Memoize
    let lazyMemoAddToOne = lazy (Memoize AddToOne)
    let lazyMemoAddToOneSkip = lazy (Memoize AddToOneSkip)
    
    member this.MemoAddToOne = lazyMemoAddToOne.Value
    member this.MemoAddToOneSkip = lazyMemoAddToOneSkip.Value

修改后,每个MyClass实例都会拥有独立的缓存字典,重复调用同一参数时会直接返回缓存值,不会重复计算。

内容的提问来源于stack exchange,提问作者Eugene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:06:17