管道的高效分块用于严格的字节串

时间:2016-06-22 23:00:38

标签: haskell conduit

这是此earlier question的后续内容。我有一个管道来源(来自Network.HTTP.Conduit)严格ByteString。我想将它们重新组合成更大的块(通过网络发送到另一个客户端,经过另一个编码并转换为lazy bytestring)。我写了chunksOfAtLeast管道,源自上面问题的答案,似乎效果很好。我想知道是否还有进一步提高性能的空间。

import Data.Conduit as C
import Control.Monad.IO.Class
import Control.Monad
import Data.Conduit.Combinators as CC
import Data.Conduit.List as CL
import Data.ByteString.Lazy as LBS hiding (putStrLn)
import Data.ByteString as BS hiding (putStrLn)

chunksOfAtLeast :: Monad m => Int -> Conduit BS.ByteString m BS.ByteString
chunksOfAtLeast chunkSize =
    loop
  where
    loop = do
        bs <- takeE chunkSize =$= ((BS.concat . ($ [])) <$> CL.fold (\front next -> front . (next:)) id)
        unless (BS.null bs) $ do
            yield bs
            loop

main = do
  yieldMany ["hello", "there", "world!"] $$ chunksOfAtLeast 8 =$ CL.mapM_ Prelude.print

1 个答案:

答案 0 :(得分:1)

获得最佳效果始终是尝试某些内容并对其进行基准测试的情况,因此我无法确定地告诉您我能为您提供更高效的内容。也就是说,将较小的数据块组合成较大的块是builders的主要目标,因此利用它们可能更有效。这是一个例子:

{-# LANGUAGE OverloadedStrings #-}
import Conduit
import Data.ByteString (ByteString)
import Data.ByteString.Builder (byteString)
import Data.Conduit.ByteString.Builder

bufferChunks :: Conduit ByteString IO ByteString
bufferChunks = mapC byteString =$= builderToByteString

main :: IO ()
main = yieldMany ["hello", "there", "world!"] $$ bufferChunks =$ mapM_C print
相关问题