Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Space leak debugging (Philip Scott)
2. Re: Space leak debugging (Daniel Fischer)
3. Re: Space leak debugging (Brandon S. Allbery KF8NH)
4. Re: Space leak debugging (Philip Scott)
5. Re: Space leak debugging (Philip Scott)
----------------------------------------------------------------------
Message: 1
Date: Thu, 03 Jun 2010 21:18:12 +0100
From: Philip Scott <[email protected]>
Subject: [Haskell-beginners] Space leak debugging
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Hello again, it's me, your favourite haskell beginner :)
This one really has me puzzled. I've got a little example here - the
program itself is a bit silly but it illustrates my problem nicely.
He's a little program:
import qualified Data.ByteString as B
chunkFiller i bs = do
if (B.null bs ) then return 1
else chunkFiller (i+1) bs
main = do
let bs = (B.singleton 10)
j <- chunkFiller 0 bs
return 1
It runs forever, which is fine, but it doesn't run in constant space. In
fact, it gobbles up all the memory until it can't get any more and dies.
I can't for the life of me work out what is going on, surely there is
some enormous thunk being built up somewhere, but for all the
Debug.Trace(), $!, seq's, and profilign outputs in the world I can't
figure out where. What is *really* interesting is that if you replace
the 'if' line with
if (B.null bs || i== -1) then return 1
(i never equals -1) then it runs in constant space! That just boggles my
mind.
As usual, any thoughts greatly appreciated.
All the best,
Philip
------------------------------
Message: 2
Date: Thu, 3 Jun 2010 23:51:40 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Space leak debugging
To: [email protected], [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
On Thursday 03 June 2010 22:18:12, Philip Scott wrote:
> Hello again, it's me, your favourite haskell beginner :)
>
> This one really has me puzzled. I've got a little example here - the
> program itself is a bit silly but it illustrates my problem nicely.
>
> He's a little program:
>
> import qualified Data.ByteString as B
>
> chunkFiller i bs = do
> if (B.null bs ) then return 1
> else chunkFiller (i+1) bs
>
> main = do
> let bs = (B.singleton 10)
> j <- chunkFiller 0 bs
> return 1
>
> It runs forever, which is fine, but it doesn't run in constant space. In
> fact, it gobbles up all the memory until it can't get any more and dies.
> I can't for the life of me work out what is going on, surely there is
> some enormous thunk being built up somewhere,
Yep.
chunkFiller 0 bs
~> chunkFiller (0+1) bs
~> chunkFiller ((0+1)+1) bs
~> chunkFiller (((0+1)+1)+1) bs
~> ...
Since the loop doesn't do much, the thunk grows really fast:
$ ./philLeak +RTS -s -M400M
./philLeak +RTS -s -M400M
Heap exhausted;
Current maximum heap size is 419430400 bytes (400 MB);
use `+RTS -M<size>' to increase it.
414,708,668 bytes allocated in the heap
1,173,761,740 bytes copied during GC
414,303,860 bytes maximum residency (11 sample(s))
5,643,660 bytes maximum slop
418 MB total memory in use (3 MB lost due to fragmentation)
Generation 0: 781 collections, 0 parallel, 2.06s, 2.16s elapsed
Generation 1: 11 collections, 0 parallel, 7.64s, 13.11s elapsed
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.26s ( 0.26s elapsed)
GC time 9.70s ( 15.27s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 9.95s ( 15.54s elapsed)
%GC time 97.4% (98.3% elapsed)
Alloc rate 1,619,867,147 bytes per MUT second
Productivity 2.6% of total user, 1.6% of total elapsed
> but for all the
> Debug.Trace(), $!, seq's, and profilign outputs in the world I can't
> figure out where.
a) BangPatterns, put a bang on the i,
chunkFiller !i bs = ...
b) else i `seq` chunkFiller (i+1) bs
c) else (chunkFiller $! i+1) bs
all of those cure the space leak.
> What is *really* interesting is that if you replace
> the 'if' line with
>
> if (B.null bs || i== -1) then return 1
>
> (i never equals -1) then it runs in constant space! That just boggles my
> mind.
bs isn't null, so it must check whether i == (-1). For that, it must
evaluate i, hence it doesn't build a thunk.
>
> As usual, any thoughts greatly appreciated.
>
> All the best,
>
> Philip
------------------------------
Message: 3
Date: Fri, 4 Jun 2010 01:25:16 -0400
From: "Brandon S. Allbery KF8NH" <[email protected]>
Subject: Re: [Haskell-beginners] Space leak debugging
To: [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"
On Jun 3, 2010, at 16:18 , Philip Scott wrote:
> that if you replace the 'if' line with
>
> if (B.null bs || i== -1) then return 1
>
> (i never equals -1) then it runs in constant space! That just
> boggles my mind.
That's your clue: since adding i there makes it run in constant
space, you must be forcing its evaluation when it otherwise was just
building thunks. So you need to make i strict with seq or case.
--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [email protected]
system administrator [openafs,heimdal,too many hats] [email protected]
electrical and computer engineering, carnegie mellon university KF8NH
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 195 bytes
Desc: This is a digitally signed message part
Url :
http://www.haskell.org/pipermail/beginners/attachments/20100604/118366b7/PGP-0001.bin
------------------------------
Message: 4
Date: Fri, 04 Jun 2010 09:12:56 +0100
From: Philip Scott <[email protected]>
Subject: Re: [Haskell-beginners] Space leak debugging
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Hi Daniel,
>
>> It runs forever, which is fine, but it doesn't run in constant space. In
>> fact, it gobbles up all the memory until it can't get any more and dies.
>> I can't for the life of me work out what is going on, surely there is
>> some enormous thunk being built up somewhere,
>>
> Yep.
>
> chunkFiller 0 bs
> ~> chunkFiller (0+1) bs
> ~> chunkFiller ((0+1)+1) bs
> ~> chunkFiller (((0+1)+1)+1) bs
> ~> ...
>
You are entirely right, thank you! I was totally fixated on the
bytestring, I never even considered it might be something to do with my
inncoent looking accumulator :)
You guys are awesome.
- Phil
------------------------------
Message: 5
Date: Fri, 04 Jun 2010 09:13:37 +0100
From: Philip Scott <[email protected]>
Subject: Re: [Haskell-beginners] Space leak debugging
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
On 03/06/2010 22:58, Markus Läll wrote:
> I'm going to guess, that the testing i for equality forces it to be
> evaluated to a integer on every iteration, so it wont grow a recursive
> i + 1 + 1 + ... thunk.
>
>
Spot on! Thank you ever so much.
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 24, Issue 4
****************************************