类似于@Gabriel Gonzalez 提出的这个问题:How to do fast data deserialization in Haskell
我有一个大 map ,里面有我使用 Cerial 序列化的整数和文本。文件大约10M。
每次我运行我的程序时,我都会反序列化整个事情,这样我就可以查找一些项目。反序列化大约需要 500 毫秒,这没什么大不了的,但我似乎总是喜欢在星期五进行分析。
当我只需要其中几个项目时,总是反序列化 100k 到 1M 项目似乎很浪费。
我试过 decodeLazy
并将 map 更改为 Data.Map.Lazy
(不是真正理解 Map 是如何惰性的,但好吧,它就在那里)并且这对时间没有影响,除非它可能有点慢。
我想知道是否有一些可以更智能的东西,只加载和解码必要的东西。当然,像 sqlite 这样的数据库可能非常大,但它只加载完成查询所需的内容。我想找到类似的东西,但不必创建数据库模式。
更新
你知道什么会很棒吗? Mongo 与 Sqlite 的一些融合。就像你可以拥有一个使用平面文件存储的 JSON 文档数据库......当然有人已经做到了 https://github.com/hamiltop/MongoLiteDB ...在 Ruby 中 :(
认为 mmap 可能会有所帮助。试过 mmap
库和段错误的 GHCI 有史以来第一次。不知道如何甚至报告该错误。
试过 bytestring-mmap
库,它可以工作,但没有性能改进。只需替换这个:
ser <- BL.readFile cacheFile
有了这个:
ser <- unsafeMMapFile cacheFile
更新 2
keyvaluehash可能只是门票。性能似乎非常好。但是 API 很奇怪并且缺少文档,因此需要进行一些试验。
更新3:我是个白痴
显然,我在这里想要的不是 map 的懒惰反序列化。我想要一个键值数据库,并且有几个可用的选项,例如 dvm、tokyo-cabinet 和这个我以前从未见过的 levelDB 东西。
Keyvaluehash 看起来是我喜欢的本地 Haskell 键值数据库,但我仍然不知道它的质量。例如,您不能要求数据库提供所有键或所有值的列表(唯一真正的操作是
readKey
、 writeKey
和 deleteKey
),因此如果您需要,则必须将其存储在其他地方。另一个缺点是您必须在创建数据库时告诉它大小。我使用了 20M 的大小,所以我有足够的空间,但它创建的实际数据库占用了 266M。不知道为什么,因为没有一行文档。
最佳答案
我过去这样做的一种方法是创建一个目录,其中每个文件都由一个序列化的键命名。可以使用 unsafeinterleaveIO 来“thunk”每个读取文件的反序列化内容,以便仅在读取时强制值...
关于performance - 如何在 Haskell 中进行 Lazy Map 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26558117/