Data.Binary最佳实践 - 何时严格以及如何实施

时间:2012-07-29 08:33:19

标签: haskell serialization

this StackOverflow question的启发,我想向社群询问有关Binary的最佳做法。当我注意到我的Hyperedge s(一个简单的代数数据结构)的大型列表不会被流式传输而是立即加载时,我编写了使用块的myGetmyPut函数。 10000个元素。正如StackOverflow问题的答案中所述,我的实现不适用于Binary> = 0.5。 (我错过了。)

但是,我还注意到,在HyperedgeInt的类型参数中加载Int32时,很多Word32和{{1} s被分配只是为了稍后转换。那是一次巨大的空间泄漏。正如您所见,我“尽快”修复了Word64 deepseqget的应用。我希望使用更精确的方法,可能使用Strategy,但是我再也不能使用Binary类型类,因为策略必须是一个额外的参数。

总结:现在,这是一团糟。你能提供“最佳实践”建议吗?

instance (NFData v, NFData l, NFData i, B.Binary v, B.Binary l, B.Binary i, Ord v)
  => B.Binary (Hyperedge v l i) where
  put e = do
    B.put (to e)
    B.put (from e)
    B.put (label e)
    B.put (ident e)
  -- get = mkHyperedge <$> B.get <*> B.get <*> B.get <*> B.get
  get = do
    x1 <- B.get
    x2 <- x1 `deepseq` B.get
    x3 <- x2 `deepseq` B.get
    x4 <- x3 `deepseq` B.get
    x4 `deepseq` return (mkHyperedge x1 x2 x3 x4)


myGet
  :: (NFData v, NFData l, NFData i, B.Binary v, B.Binary l, B.Binary i, Ord v) 
  => B.Get [Hyperedge v l i]
myGet = do
  es1 <- B.get
  if null es1
    then return []
    else
      do
        es2 <- myGet
        return (es1 ++ es2)

myPut
  :: (NFData v, NFData l, NFData i, B.Binary v, B.Binary l, B.Binary i, Ord v) 
  => [Hyperedge v l i] -> B.Put
myPut es@[] = B.put es -- ([] :: [Hyperedge v l i])
myPut es = do
  B.put (take 10000 es)
  myPut (drop 10000 es)

0 个答案:

没有答案