gpt4 book ai didi

serialization - 序列化和计数值列表

转载 作者:行者123 更新时间:2023-12-04 07:40:18 25 4
gpt4 key购买 nike

我需要使用自定义编码函数(我有)序列化一个大的值列表。我已经这样做了并且它有效,但我也想让它计算有多少值被序列化并写入磁盘,同时仍然使用相对恒定的内存量(即它不应该需要保留整个输入列出来,因为它变得非常大)。

不需要保持计数,二进制, Cereal 和火焰生成器都可以工作(使用等效于 B.writeFile "foo" . runPut . mapM_ encodeValue );但是无论我尝试使用这些库中的任何一个做什么,似乎生成的 ByteString 都会保留在内存中直到它完成,而不是在块可用时立即开始写入磁盘(即使使用 toByteStringIO 时)来自火焰 builder )。

这是一个最小的例子,展示了我一直在尝试做的事情:

import Data.Binary
import Data.Binary.Put
import Control.Monad(foldM)
import qualified Data.ByteString.Lazy as B

main :: IO ()
main = do let ns = [1..10000000] :: [Int]
(count,b) = runPutM $ foldM (\ c n -> c `seq` (put n >> return (c+1))) (0 :: Int) ns
B.writeFile "testOut" b
print count

当编译并运行时 +RTS -hy ,结果是一个几乎由 ByteString 值支配的三角形图。

到目前为止我发现的唯一解决方案(我不是它的忠实粉丝)是使用 foldM 在 IO 中进行循环(直接或使用 B.appendFile )而不是在 Put 内或直接构造一个 Builder 值,这对我来说似乎不是很优雅。有没有更好的办法?

最佳答案

我有点惊讶 toByteStringIO不起作用,希望更熟悉该库的人会提供答案。

话虽如此,每当我想将流处理与 IO 操作混合在一起时,我通常会发现 iteratees 是最优雅的解决方案。这是因为它们允许精确控制处理和保留多少数据,并将流方面与其他任意 IO 操作相结合。有several iteratee implementations关于黑客攻击;这个例子是“iteratee”,因为它是我最熟悉的。

import Data.Binary.Put
import Control.Monad
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy as B
import Data.ByteString.Lazy.Internal (defaultChunkSize)
import Data.Iteratee hiding (foldM)
import qualified Data.Iteratee as I

main :: IO ()
main = do
let ns = [1..80000000] :: [Int]
iter <- enumPureNChunk ns (defaultChunkSize `div` 8)
(joinI $ serializer $ writer "testOut")
count <- run iter
print count

serializer = mapChunks ((:[]) . runPutM . foldM
(\ !cnt n -> put n >> return (cnt+1)) 0)

writer fp = I.foldM
(\ !cnt (len,ck) -> liftIO (B.appendFile fp ck) >> return (cnt+len))
0

这包括三个部分。 writer是“迭代者”,即数据消费者。它在接收到的数据时写入每个数据块,并保持对长度的运行计数。 serializer是一个流转换器,又名“枚举”。它需要一个类型为 [Int] 的输入块并将其序列化为类型为 [(Int, B.ByteString)] 的流(元素数,字节串)。最后 enumPureNChunk是“枚举器”,它产生一个流,在这种情况下来自输入列表。它从输入中获取足够的元素来填充单个惰性字节串块(我在 64 位上,对于 32 位系统除以 4),然后将它们写入磁盘,以便可以进行 GC。

关于serialization - 序列化和计数值列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7020854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com