如何在Haskell中进行Lazy Map反序列化

时间:2014-10-25 00:27:25

标签: performance haskell serialization deserialization lazy-loading

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

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

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

当我只需要一些项目时,总是将100k到100个项目反序列化似乎很浪费。

我尝试了decodeLazy并且还将地图更改为Data.Map.Lazy(不是真正了解地图可以如何懒惰,但确定,它就在那里)并且这对时间没有影响,除非它可能是慢一点。

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

更新

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

思想mmap可能有所帮助。第一次尝试mmap库和segfaulted GHCI。不知道怎么能报告那个bug。

尝试了bytestring-mmap库并且它有效但没有性能改进。只需替换它:

ser <- BL.readFile cacheFile

有了这个:

ser <- unsafeMMapFile cacheFile

更新2

keyvaluehash可能只是门票。表现似乎非常好。但API很奇怪,缺少文档,因此需要进行一些实验。

更新3:我是个白痴

显然,我想要的不是地图的更加懒惰的反序列化。我想要一个键值数据库,有几个选项可供选择,比如dvm,tokyo-cabinet和我以前从未见过的这个levelDB。

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

1 个答案:

答案 0 :(得分:1)

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