在 F# 中实现一个自定义字符串类型来对字符串进行interning。我需要将大型 CSV 文件读入内存。鉴于大多数列是分类的,值是重复的,因此首次遇到该值时创建新字符串并仅在后续出现时引用它以节省内存是有意义的。
在 C# 中,我通过创建全局 intern 池 (concurrent dict) 并在设置值之前查找字典是否已经存在来实现这一点。如果存在,只需指向已经在字典中的字符串。如果没有,将其添加到字典中,并将值设置为刚刚添加到字典中的字符串。
对于新手而言,不知道在 F# 中做这个最好的方法是什么。将使用记录命名元组等中的新字符串类型,并且它必须与并发进程一起工作。
编辑:
我应该提到,我实际上无法找出如何在 F# 中执行 C# 方法(除了实现 C# 类型并在 F# 中使用它)。
缓存模式与我所寻找的略有不同吗?我们不是缓存计算结果——我们确保每个字符串对象最多只创建一次,并且所有后续创建的相同字符串只是对原始字符串的引用。使用字典来完成这一点是一种方法,使用 String.Intern 是另一种方法。
如果我漏掉了什么显而易见的东西,请原谅。
在 C# 中,我通过创建全局 intern 池 (concurrent dict) 并在设置值之前查找字典是否已经存在来实现这一点。如果存在,只需指向已经在字典中的字符串。如果没有,将其添加到字典中,并将值设置为刚刚添加到字典中的字符串。
对于新手而言,不知道在 F# 中做这个最好的方法是什么。将使用记录命名元组等中的新字符串类型,并且它必须与并发进程一起工作。
编辑:
String.Intern
使用 Intern Pool。我的理解是,对于大型池,它不是非常高效,并且不会被垃圾回收,即任何/所有 interned 字符串都将在应用程序的生命周期内保留在 intern pool 中。想象一个应用程序,在其中你读取一个文件,执行一些操作并写入数据。使用 Intern Pool 解决方案可能有效。现在想象你要做同样的事情 100 次,每个文件中的字符串都很少相同。如果在堆上分配内存,在处理每个文件后,我们可以强制垃圾收集器清除不必要的字符串。我应该提到,我实际上无法找出如何在 F# 中执行 C# 方法(除了实现 C# 类型并在 F# 中使用它)。
缓存模式与我所寻找的略有不同吗?我们不是缓存计算结果——我们确保每个字符串对象最多只创建一次,并且所有后续创建的相同字符串只是对原始字符串的引用。使用字典来完成这一点是一种方法,使用 String.Intern 是另一种方法。
如果我漏掉了什么显而易见的东西,请原谅。
String.Intern
,而要自己编写代码呢? - kvb