Lazy ByteString: memory hacking in some cases

Below we have two seemingly functionally equivalent programs. For the first, the memory remains constant, while for the second, the memory explodes (using ghc 7.8.2 and bytestring-0.10.4.0 in Ubuntu 14.04 64-bit):

Doesn't explode:

--NoExplode.hs
--ghc -O3 NoExplode.hs
module Main where
import Data.ByteString.Lazy as BL
import Data.ByteString.Lazy.Char8 as BLC

num = 1000000000
bytenull = BLC.pack ""

countDataPoint arg sum
  | arg == bytenull = sum
  | otherwise = countDataPoint (BL.tail arg) (sum+1)

test1 = BL.last $ BL.take num $ BLC.cycle $ BLC.pack "abc" 
test2 = countDataPoint (BL.take num $ BLC.cycle $ BLC.pack "abc") 0

main = do
  print test1
  print test2

Explosion:

--Explode.hs
--ghc -O3 Explode.hs
module Main where
import Data.ByteString.Lazy as BL
import Data.ByteString.Lazy.Char8 as BLC

num = 1000000000
bytenull = BLC.pack ""

countDataPoint arg sum
  | arg == bytenull = sum
  | otherwise = countDataPoint (BL.tail arg) (sum+1)

longByteStr = BL.take num $ BLC.cycle $ BLC.pack "abc" 

test1 = BL.last $ longByteStr
test2 = countDataPoint (BL.take num $ BLC.cycle $ BLC.pack "abc") 0

main = do
  print test1
  print test2

Additional Information:

The difference is that in Explode.hsI took BL.take num $ BLC.cycle $ BLC.pack "abc"from the definition test1and assigned it to my own meaning longByteStr.

Strangely enough, if we will comment on either print test1, or print test2in Explode.hs(but obviously not both), then the program will not explode.

Is there a memory of the causes of the explosion in Explode.hs, and not in NoExplode.hs, and why is the exploding program ( Explode.hs) required both print test1, and print test2in order to exlode?

+4
1

ghc , ? . , , . .

-ddump-simp . SO: GHC


ghc-7.8.2. . -ddump-simpl. , .


. print test1 , , , . print test2 - , GC'ed .

. print test1 , GC'ed, print test2. print , .

print, GC'ed " " . .

PS. "GC'ed" ": print stdout. GC. prints ..

+4

Source: https://habr.com/ru/post/1545096/


All Articles