[Haskell-cafe] Streaming bytes and performance

Konstantin Litvinenko to.darkangel at gmail.com
Tue Mar 19 14:40:37 CET 2013


On 03/18/2013 02:14 PM, Gregory Collins wrote:
> Put a bang pattern on your accumulator in "go". Since the value is not
> demanded until the end of the program, you're actually just building up
> a huge space leak there.

Fixed that

> Secondly, unconsing from the lazy bytestring will cause a lot of
> allocation churn in the garbage collector -- each byte read in the input
> forces the creation of a new "L.ByteString", which is many times larger.

Nope. L.ByteString is created along with strict ByteString but content 
not copied. And, in fact, that not a problem. The problem is that GHC 
unable to optimize constantly changing state in State monad. I don't 
know is it posible or not and if it is than what should I do to allow 
such optimization.

import Control.Monad.State.Strict

data S6 = S6 Int Int

main_6 = do
     let r = evalState go (S6 10000 0)
     print r
   where
     go = do
         (S6 i a) <- get
         if (i == 0) then return a else put (S6 (i - 1) (a + i)) >> go

main_7 = do
     let r = go (S6 10000 0)
     print r
   where
     go (S6 i a)
         | i == 0 = a
         | otherwise = go $ S6 (i - 1) (a + i)

main = main_7

If I run main_6 I get constant allocations. If I run main_7 I get no 
allocations.

Does anybody know how to overcome this inefficiency?




More information about the Haskell-Cafe mailing list