2016-06-22 3 views
0

이것은 earlier question의 후속 조치입니다. 나는 콘센트 소스 (Network.HTTP.Conduit에서)가 엄격한 ByteString입니다. 나는 그들을 더 큰 덩어리로 재결합 (네트워크를 통해 또 다른 클라이언트로 보내고, 또 다른 인코딩과 게으른 바이트 테스트로 변환 한 후)하고 싶습니다. 나는 위의 질문에서 꽤 잘 작동하는 것으로 보이는 대답에서 파생 된 chunksOfAtLeast 관문을 썼습니다. 성능 향상을위한 추가 범위가 있는지 궁금합니다.엄격한 bytestring을위한 도관의 효율적인 청크

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

프로파일 러는 무엇을 말합니까? – jamshidh

+0

필자는 기준 마이크로 벤치 마크 대신 'RTS -s'를 통해 이것을 테스트했습니다. AWS 미디어 m3 인스턴스에서 코어 당 약 30MB/s 처리량을 얻을 수 있습니다. 꽤 괜찮은 것 같습니다. 그냥 내가 사용할 수있는 다른 성능 트릭이 있는지 궁금해. 또는 이것이 좋은만큼 좋다면. – Sal

답변

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 
+0

감사합니다. 덩어리를 결합하기 위해'빌더 (builder) '를 사용하는 것이 좋은 팁입니다. – Sal