Это продолжение этого более раннего вопроса. У меня есть источник канала (от Network.HTTP.Conduit
), который является строгим 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
RTS -s
вместо микробенчмаркинга критерия. Я получаю пропускную способность около 30 МБ/с на ядро (на среднем экземпляре AWS m3). Мне кажется вполне прилично. Просто любопытно, есть ли какие-нибудь другие трюки с производительностью, которые я мог бы использовать. Или если это настолько хорошо, насколько это возможно. - person Sal   schedule 23.06.2016