这是此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
答案 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