【问题标题】:Weak-memoizing result of multi-parameter function in OCamlOCaml中多参数函数的弱记忆结果
【发布时间】:2012-04-20 19:20:51
【问题描述】:

我正在寻找一种方法来记忆 OCaml 函数 f 的结果,该函数需要两个参数(通常是更多参数)。此外(这是困难的部分),如果这两个参数的任何一个值被垃圾回收,我希望这个过程的映射完全忘记结果。

对于只接受一个参数的函数,这可以通过Weak 模块及其Make 函子以一种直接的方式完成。为了将其推广到可以记忆更高元函数的东西,一个天真的解决方案是创建一个从值元组到结果值的弱映射。但这对于垃圾回收将无法正常工作,因为值的元组仅存在于 memoization 函数的范围内,而不是调用 f 的客户端代码。事实上,弱引用将指向元组,它会在记忆化后立即被垃圾回收(在最坏的情况下)。

有没有办法在不重新实现Weak.Make 的情况下做到这一点?

Hash-consing 与我的要求是正交的,事实上,对于我的价值观来说并不是真正可取的。

谢谢!

【问题讨论】:

    标签: caching ocaml weak-references memoization


    【解决方案1】:

    您可以使用树结构来代替元组索引。您将有一个由第一个函数参数索引的弱表,其条目是辅助弱表。辅助表将由第二个函数参数索引并包含记忆结果。一旦任何一个函数参数被GCed,这个结构就会忘记记忆的函数结果。但是,只要第一个函数参数有效,辅助表本身就会保留。根据您的函数结果的大小和不同的第一个参数的分布,这可能是一个合理的权衡。

    我也没有测试过这个。这似乎也相当明显。

    【讨论】:

    • 我可以看到第一个参数值的垃圾收集如何导致为第二个参数释放相应的表。但是,对第二个参数的表中的值进行 GC 对其父级没有任何作用(如果使用了 Weak 模块),即使结果映射为空。当然,这可以通过主动扫描映射的内容并删除映射到空表的任何第一个参数键来完成。
    • 对,就像我说的,在释放第一个参数之前不会收集辅助表。但是会收集记忆的返回值(在我看来)。
    【解决方案2】:

    一个想法是执行您自己的垃圾回收。

    为简单起见,我们假设所有参数都具有相同的类型k

    除了包含k * k 键控的记忆结果的主弱表之外,创建一个包含k 类型的单个参数的辅助弱表。这个想法是偶尔扫描主表并删除不再需要的绑定。这是通过查找辅助表中的参数来完成的;那么如果它们中的任何一个消失了,你就从主表中删除绑定。

    (免责声明:我没有对此进行测试;它可能不起作用或可能有更好的解决方案)

    【讨论】:

    • 好点。可能只需要一张表,一张以弱引用元组作为键的表,并且每当键元组中的任何弱引用消失时,它都会每隔一段时间进行一次自定义垃圾收集。这可以通过终结器来完成吗?
    【解决方案3】:

    我知道这是一个老问题,但我的同事最近开发了一个增量计算库,称为 Adapton,它可以处理此功能。您可以找到代码here。您可能想要使用 LazySABidi 函子(其他函子用于基准测试)。您可以在 Applications 文件夹中查看如何使用该库的示例。如果您还有其他问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 2013-08-20
      • 1970-01-01
      • 2013-01-05
      • 2012-09-05
      • 2015-03-20
      • 2019-01-21
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多