引用相同的数据和内存分配

Nik*_*kov 7 memory haskell pointers

请考虑以下数据模型:

data Artist = Artist Text
data Song = Song Artist Text
data Catalogue = Catalogue (Set Artist) (Set Song)
Run Code Online (Sandbox Code Playgroud)

你可以看到s和Artists都引用了Songs Catalogue.该Catalogue包含提及的所有艺术家列表SongS,所以相同的价值观Artist得到从两个地方提到.

假设我们Catalogue使用以下函数的多个应用程序生成值:

insertSong :: Song -> Catalogue -> Catalogue
insertSong song@(Song artist title) (Catalogue artists songs) =
  Catalogue (Set.insert artist artists) (Set.insert song songs)
Run Code Online (Sandbox Code Playgroud)

很明显,Catalogue将通过引用ArtistSongs 引用的相同值来填充,从而通过不存储这些值的副本来节省内存.

问题是,当我试图通过单独反序列化一组艺术家和一组歌曲重新从串行数据目录,应用占据比时所产生的同样价值的方式更多的内存Catalogue使用insertSong.我怀疑它是由s和Artists引用的相同s 之间丢失的关系引起SongCatalogue,这就是为什么我得到Artist占用额外内存的值的副本.

我看到的唯一解决方案是首先对这组艺术家进行反序列化,然后在强制替换Artist第一组中的值的同时反序列化这组歌曲.

所以我的问题是:

  1. 我是否正确怀疑?
  2. 我看到的解决方案是否有效?
  3. 有没有更好的方法来解决这个问题?

Rom*_*aka 6

  1. 这听起来似乎有道理.
  2. 如果做得对,它应该工作.特别是,您必须确保对所有内容进行热切评估,以避免从thunk中引用旧的Text值.
  3. 您可以选择更智能的序列化格式.例如,序列化歌曲时,请将艺术家的索引存储在艺术家列表中,而不是完整的艺术家名称.然后在反序列化期间查找它.

请注意,如果对字符串进行任何类型的计算(即使artist1并且artist2相同且共享,f artist1并且f artist2可能不是),共享也将丢失.如果这成为问题,您也可以对数据结构进行类似的更改.


Nik*_*kov 1

我偶然发现了一个解决这个问题的项目。请参阅RefSerialize