【问题标题】:How to do Lazy Map deserialization in Haskell如何在 Haskell 中进行 Lazy Map 反序列化
【发布时间】:2014-10-25 00:27:25
【问题描述】:

与@Gabriel Gonzalez 提出的这个问题类似:How to do fast data deserialization in Haskell

我有一个很大的地图,里面有我使用 Cerial 序列化的整数和文本。文件大约10M。

每次我运行我的程序时,我都会反序列化整个事情,这样我就可以查找一些项目。反序列化大约需要 500 毫秒,这没什么大不了的,但我似乎总是喜欢在星期五进行分析。

当我只需要其中的几个时,总是将 100k 反序列化为 1M 似乎很浪费。

我尝试了decodeLazy 并将地图更改为Data.Map.Lazy(不太了解地图如何变得懒惰,但是好的,它就在那里),这对时间没有影响,除非它有点慢。

我想知道是否有一些更智能的东西,只加载和解码必要的东西。当然,像 sqlite 这样的数据库可能非常大,但它只加载完成查询所需的内容。我想找到类似的东西,但不必创建数据库架构。

更新

你知道什么会很棒吗? Mongo 与 Sqlite 的一些融合。就像你可以拥有一个使用平面文件存储的 JSON 文档数据库......当然有人已经在 Ruby 中做到了 https://github.com/hamiltop/MongoLiteDB ... :(

认为 mmap 可能会有所帮助。有史以来第一次尝试了mmap 库和 GHCI 段错误。甚至不知道如何报告该错误。

尝试了bytestring-mmap 库,它可以工作,但没有性能提升。只是替换这个:

ser <- BL.readFile cacheFile

有了这个:

ser <- unsafeMMapFile cacheFile

更新 2

keyvaluehash 可能只是门票。性能似乎真的很好。但是 API 很奇怪,并且缺少文档,因此需要进行一些试验。

更新 3:我是个白痴

显然,我在这里想要的不是更延迟的 Map 反序列化。我想要一个键值对数据库,并且有几个可用的选项,例如 dvm、tokyo-cabinet 和这个我以前从未见过的 levelDB 东西。

Keyvaluehash 看起来是我喜欢的原生 Haskell 键值数据库,但我仍然不知道质量如何。例如,您不能向数据库询问所有键或所有值的列表(唯一真正的操作是readKeywriteKeydeleteKey),因此如果您需要,则必须将其存储在其他地方。另一个缺点是您必须在创建数据库时告诉它大小。我使用了 20M 的大小,所以我有足够的空间,但它创建的实际数据库占用 266M。不知道为什么,因为没有一行文档。

【问题讨论】:

  • 您的问题与 Gabriel 的问题不同(而且更有趣!)。他想要原始速度反序列化整个数据集;您只想解码(也许是读取)需要的内容。我认为您不会找到即插即用的解决方案。假设您想在 Map 中查找项目,在没有特别聪明的随机访问反序列化方案的情况下,您是否不必至少反序列化所有密钥?
  • 我从来没有尝试过这样的事情,但是:使用自定义序列化结构来记录流中的键及其偏移量。然后使用 thunk 将键反序列化为它们的值反序列化器。如果您不想反序列化所有键,则不能使用Data.Map,并且键查找将更多地涉及流上的二进制搜索或其他内容。你可以使用(记忆的)Key -&gt; Value 函数,如果这就是你所需要的。
  • 您可以使用persistent 之类的东西,它得到了很好的支持。如果您还没有,请忘记keyvaluehash。它是一个玩具,现在是一个死玩具。

标签: performance haskell serialization deserialization lazy-loading


【解决方案1】:

我过去这样做的一种方法是创建一个目录,其中每个文件都由序列化键命名。可以使用 unsafeinterleaveIO 来“thunk”每个读取文件的反序列​​化内容,以便仅在读取时强制读取值...

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2015-01-05
    • 2023-03-18
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 2018-07-16
    • 1970-01-01
    相关资源
    最近更新 更多