7

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

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

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

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

谢谢!

4

3 回答 3

3

一种想法是执行您自己的垃圾收集。

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

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

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

于 2012-04-07T17:00:00.600 回答
3

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

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

于 2012-04-07T22:19:59.483 回答
1

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

于 2013-12-16T00:42:48.487 回答