Re: a compiled program is slower than byte code
On 09/02/2011 04:35, Kazu Yamamoto (山本和彦) wrote: Hello Simon, $ ghc-nightly2 ./kazu.hs -O2 -fforce-recomp; time ./kazu [1 of 1] Compiling Main ( kazu.hs, kazu.o ) Linking kazu ... 4.17s real 4.16s user 0.01s system 99% ./kazu OK. I ran it on 32bit Linux. 6.12.3 runghc -- 2.22s user 0.40s system 96% cpu 2.724 total ghc -- 1.96s user 0.14s system 97% cpu 2.151 total ghc -O -- 2.18s user 0.10s system 97% cpu 2.333 total ghc -O2 -- 2.27s user 0.07s system 97% cpu 2.393 total ghc-7.0 runghc -- 3.43s user 0.35s system 97% cpu 3.861 total ghc -- 5.11s user 0.07s system 97% cpu 5.299 total ghc -O -- 5.38s user 0.03s system 97% cpu 5.534 total ghc -O2 -- 5.54s user 0.10s system 97% cpu 5.783 total Thanks, I do see the problem now (I was inadvertently running the compiled code with runghc, because I used runghc foo.hs -fforce-recomp, which doesn't do what I thought it did). I created a ticket: http://hackage.haskell.org/trac/ghc/ticket/4951 I think the difference between interpreted and compiled is due to http://hackage.haskell.org/trac/ghc/ticket/917. What I'm more worried about is the slowdown in pre-7.0.2 relative to other versions. HEAD is more than twice as fast on this program. Fusion not working, perhaps? Here is the results of ghc -O -ddump-simpl-stats: ghc-7.0: 19 RuleFired 6 ++ 2=# 1 fold/build 5 foldr/app 1 foldr/augment 1 foldr/single 1 map 1 unpack 1 unpack-list 6.12.3: 25 RuleFired 6 ++ 2=# 3 fold/build 6 foldr/app 1 foldr/augment 1 map 2 repeat 2 take 1 unpack 1 unpack-list My stats look very different. 6 RuleFired 1 ++ 2 =# 1 foldr/app 1 unpack 1 unpack-list Are your libraries compiled with -O2? Cheers, Simon ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: a compiled program is slower than byte code
Hello, My stats look very different. 6 RuleFired 1 ++ 2 =# 1 foldr/app 1 unpack 1 unpack-list Are your libraries compiled with -O2? I don't know. How can I check? I just installed ghc-7.0 by perl boot; configure; make; make install. --Kazu ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Deriviable type classes
Friends Just a heads-up. Pedro is working on implementing Generic Defaults, as described in his Haskell Symposium 2010 paper www.dreixel.net/research/pdf/gdmh_nocolor.pdf It will replace (and improve on) the Derivable type classes stuff in GHC at the moment, which was originally presented in a paper of that title that Ralf and I wrote in the 2000 Haskell workshop http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm. The Derivable type class extension is barely used, I believe, and isn't even documented in the manual. So I propose to switch from one to the other, rather than to try to support both. This change will happen in GHC 7.2 or 7.4, depending on when Pedro is done. Please yell if you are a secret user of derivable type classes, so this change would discombobulate you. Simon ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Deriviable type classes
Hi, 2011/2/9 Simon Peyton-Jones simo...@microsoft.com Friends Just a heads-up. Pedro is working on implementing Generic Defaults, as described in his Haskell Symposium 2010 paper www.dreixel.net/research/pdf/gdmh_nocolor.pdf It will replace (and improve on) the Derivable type classes stuff in GHC at the moment, which was originally presented in a paper of that title that Ralf and I wrote in the 2000 Haskell workshop http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm. The Derivable type class extension is barely used, I believe, and isn't even documented in the manual. Isn't it this?: http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html But anyway, I can't remember seeing any use of it. Cheers, Pedro ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
RE: Deriviable type classes
The Derivable type class extension is barely used, I believe, and isn't even documented in the manual. Isn't it this?: http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html Oh yes, silly me. It is documented! Simon From: José Pedro Magalhães [mailto:j...@cs.uu.nl] Sent: 09 February 2011 12:20 To: Simon Peyton-Jones Cc: GHC users Subject: Re: Deriviable type classes Hi, 2011/2/9 Simon Peyton-Jones simo...@microsoft.commailto:simo...@microsoft.com Friends Just a heads-up. Pedro is working on implementing Generic Defaults, as described in his Haskell Symposium 2010 paper www.dreixel.net/research/pdf/gdmh_nocolor.pdfhttp://www.dreixel.net/research/pdf/gdmh_nocolor.pdf It will replace (and improve on) the Derivable type classes stuff in GHC at the moment, which was originally presented in a paper of that title that Ralf and I wrote in the 2000 Haskell workshop http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm. The Derivable type class extension is barely used, I believe, and isn't even documented in the manual. Isn't it this?: http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html But anyway, I can't remember seeing any use of it. Cheers, Pedro ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Deriviable type classes
2011/2/9 Simon Peyton-Jones: Friends Just a heads-up. Pedro is working on implementing Generic Defaults, as described in his Haskell Symposium 2010 paper www.dreixel.net/research/pdf/gdmh_nocolor.pdf It will replace (and improve on) the Derivable type classes stuff in GHC at the moment, which was originally presented in a paper of that title that Ralf and I wrote in the 2000 Haskell workshop http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm. The Derivable type class extension is barely used, I believe, and isn't even documented in the manual. So I propose to switch from one to the other, rather than to try to support both. This change will happen in GHC 7.2 or 7.4, depending on when Pedro is done. Please yell if you are a secret user of derivable type classes, so this change would discombobulate you. The only time I came across a use of it was in James Cheney's FreshLib [1]. I don't know if the latest version still uses it, though. There was also this bug [2] that prevented FreshLib from being compiled, but that is apparently fixed now. [1] http://homepages.inf.ed.ac.uk/jcheney/programs/freshlib/ [2] http://hackage.haskell.org/trac/ghc/ticket/2824 Regards, Sean ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
my RULES don't fire
Hello, I want to use the RULES pragma and cannot get my rules to fire. Here is a simplified example of what I'm trying. I define my own version of foldMap for lists: fold :: Monoid m = (a - m) - [a] - m fold f = foldr mappend mempty . map f -- alternative, trying to avoid interference with foldr/build fusion -- fold _ [] = mempty -- fold f (x:xs) = f x `mappend` fold f xs {-# NOINLINE fold #-} I try using a NOINLINE pragma to make the firing of my rules (which involve fold) more robust. But they don't fire with or without NOINLINE. Also the uncommented version does not make a difference. I also define a function that creates a singleton list: single :: a - [a] single x = [x] {-# NOINLINE single #-} Now I want to replace calls of `fold f . g single` (or eta-expanded versions of this) by `g f` using the following rules: {-# RULES monoid fusion pointfree forall f (g :: forall m . Monoid m = (a - m) - b - m) . fold f . g single = g f; monoid fusion pointed, general forall f (g :: forall m . Monoid m = (a - m) - b - m) b . fold f (g single b) = g f b; monoid fusion pointed, for lists forall f (g :: forall m . Monoid m = (a - m) - [a] - m) xs . fold f (g single xs) = g f xs; #-} The variations of type signatures (including no signatures at all) for the pattern variables that I tried did not change anything for the better. I wrote the third rule only because the second gives a warning that I don't quite understand: Warning: Forall'd type variable b is not bound in RULE lhs fold @ m @ a $dMonoid f (g @ [a] $dMonoid (single @ a) b) I try out the rules using the following function that takes the role of `g` in the rules: idGen :: Monoid m = (a - m) - [a] - m idGen _ [] = mempty idGen f (x:xs) = f x `mappend` idGen f xs {-# NOINLINE idGen #-} Again, I use NOINLINE just in case that would help the rules fire. Here is a main function where the rules should fire: main :: IO () main = do print ((fold id . idGen single) [[()]]) print (fold id (idGen single [[()]])) But they don't. Why don't the rules fire, what can I change such that they do, and what to get rid of the warning for the second rule (which I think is the one I should use)? Best regards, Sebastian Here is the output of -ddump-simple-stats (once with -fenable-rewrite-rules only and once with -O): # ghc --version The Glorious Glasgow Haskell Compilation System, version 7.0.1 # ghc -fenable-rewrite-rules -fforce-recomp -ddump-simpl-stats --make rules [1 of 1] Compiling Main ( rules.hs, rules.o ) Grand total simplifier statistics Total ticks: 0 1 SimplifierDone 1 # ghc -O -fforce-recomp -ddump-simpl-stats --make rules [1 of 1] Compiling Main ( rules.hs, rules.o ) FloatOut stats: 0 Lets floated to top level; 0 Lets floated elsewhere; from 4 Lambda groups FloatOut stats: 10 Lets floated to top level; 1 Lets floated elsewhere; from 5 Lambda groups Grand total simplifier statistics Total ticks: 144 34 PreInlineUnconditionally 1 eta_Xp5 1 g_amr 1 eta_amx 1 k_amJ 1 z_amK 1 f_amQ 1 g_amR 1 x_amS 1 k_an9 1 z_ana 1 g_anb 1 f_anf 1 xs_ang 1 eta_aoA 2 $dShow_aKW 2 x_aKX 1 ys_aVd 1 c_dmm 1 n_dmn 1 a_snX 1 a_so1 1 lvl_sod 1 lvl_soe 1 lvl_sof 1 lvl_sog 1 lvl_soh 1 lvl_soi 1 lvl_soj 1 a_son 1 a_sop 1 a_sV0 1 a_sV2 17 PostInlineUnconditionally 1 k_amv 1 f_amQ 1 g_amR 1 c_ani 1 n_anj 1 m_anI 1 k_anJ 2 $dShow_aoy 2 x_aoz 1 c_aVa 1 f_aVb 1 x_aVc 1 a_snV 1 a_snZ 1 lvl_sVA 15 UnfoldingDone 1 GHC.Base.build 1 GHC.Base.foldr 2 System.IO.print 1 GHC.TopHandler.runMainIO 2 GHC.Base.. 1 GHC.Base.mapFB 1 GHC.Base.$fMonadIO_$c 2 Main.main 2 System.IO.print1 2 GHC.Show.$fShow[]_$cshow 8 RuleFired 1 Class op 2 Class op show 2 Class op showList 1 fold/build 1 foldr/nil 1 map 8 LetFloatFromLet 8 62 BetaReduction 1 eta_Xp5 1 a_amq 1 g_amr 1 a_amt 1 b_amu 1 k_amv 1 z_amw 1 eta_amx 1 b_amH 1 a_amI 1 k_amJ 1 z_amK 2 b_amN 2 c_amO 2 a_amP 2 f_amQ 2 g_amR 1 x_amS 1 a_an7 1 b_an8 1 k_an9 1 z_ana 1 g_anb 1 a_and 1 a1_ane 1 f_anf 1 xs_ang 1 b_anh 1 c_ani 1 n_anj 1 a_anG 1 b_anH 1 m_anI 1 k_anJ 2 a_aox 2 $dShow_aoy 2 x_aoz 1 eta_aoA 2 a_aKV 2 $dShow_aKW 2 x_aKX 1 elt_aV7 1 lst_aV8 1 a_aV9 1 c_aVa 1 f_aVb 1 x_aVc 1 ys_aVd 1 a_dml 1 c_dmm 1 n_dmn 13 SimplifierDone 13
Re: my RULES don't fire
On Wednesday 09 February 2011 16:23:15, Sebastian Fischer wrote: Why don't the rules fire, what can I change such that they do, and what to get rid of the warning for the second rule (which I think is the one I should use)? Didn't spot that, sorry. Best regards, Sebastian Here is the output of -ddump-simple-stats (once with -fenable-rewrite-rules only and once with -O): Users guide says: (NB: enabling -fenable-rewrite-rules without -O may not do what you expect, though, because without -O GHC ignores all optimisation information in interface files; ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
RE: Dictionaries and full laziness transformation
In general it's quite hard to solve this problem without risking losing sharing. However in this case I added a simple arity analyser after the 7.0.1 release which solves the problem. It'll be in 7.0.2. Try with HEAD and check it does what you expect. Simon | -Original Message- | From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell- | users-boun...@haskell.org] On Behalf Of Akio Takano | Sent: 07 February 2011 04:10 | To: glasgow-haskell-users@haskell.org | Subject: Dictionaries and full laziness transformation | | Hi, | | I'm using GHC 7.0.1. I found that recursive overloaded functions tend | to leak memory when compiled with full-laziness optimization on. Here | is a simple case. | | -- TestSub.hs | {-# LANGUAGE BangPatterns #-} | module TestSub where | | {-# NOINLINE factorial #-} | factorial :: (Num a) = a - a - a | factorial !n !acc = if n == 0 then acc else factorial (n - 1) (acc * n) | | -- main.hs | import TestSub | | factorial1 :: Int - Int - Int | factorial1 = factorial | | main = do | n - readLn | print $ factorial1 n 1 | | main | | This program should run in constant space, and compiled with -O0 or | -O2 -fno-full-laziness, it does. However with -O2, it takes a linear | amount of memory. The core for factorial looks like this: | | TestSub.factorial = | \ (@ a_ajm) ($dNum_slz :: GHC.Num.Num a_ajm) - | let { | a_slA :: GHC.Classes.Eq a_ajm | [LclId] | a_slA = GHC.Num.$p1Num @ a_ajm $dNum_slz } in | let { | lvl2_slC :: a_ajm - a_ajm - a_ajm | [LclId] | lvl2_slC = TestSub.factorial @ a_ajm $dNum_slz } in | ... | | The problem is that lvl2_slC closure is created whenever factorial is | applied to a Num dictionary, and kept alive until that application is | GCed. In this program it never happens, because an application to the | Num Int dictionary is referred to by the factorial1 CAF, and it | recursively keeps the whole chain of closures alive. | | I know that full laziness transformation *sometimes* causes a space | leak, but this looks like a bad result to me, because: | | - It looks like there is no point building a lot of equivalent | closures, instead of one. | - A lot of code can suffer from this behavior, because overloaded | recursive functions are fairly common. | For example, unfoldConvStream function from the latest iteratee | package suffers from this problem, if I understand correctly. | | Does anyone have an idea on whether this can be fixed in GHC, or how | to work around this problem? | | Regards, | | Takano Akio | | ___ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: my RULES don't fire
On Wednesday 09 February 2011 16:23:15, Sebastian Fischer wrote: Why don't the rules fire, Because the 'match' is at the wrong type. In main, idGen appears as idGen_anJ :: ([()] - [[()]]) - [[()]] - [[()]] at some point (yay for ghc -v4), so it doesn't match g's polymorphic type. what can I change such that they do, Type signatures. and what to get rid of the warning for the second rule (which I think is the one I should use)? I'll let that for somebody else. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: RFC: migrating to git
In my one serious attempt to use git for one of my own projects, some seemingly-innocuous operation deleted a file on me and I lost a couple hours of work. I agree with the people who have said that git's documentation and semantics are highly confusing, moreso than darcs's. For example, what does it mean to stage a commit? Why is there an entire GUI window for this presumably-important action, and why do things I think I've committed not appear in the change history or mysteriously reverse themselves? If ghc went to git, it wouldn't make me less likely to contribute, but I would do so by checking everything into a local darcs repo and using that to track my own changes, then letting somebody else do the work of getting them into git! Which probably would reduce the likelihood of my patch being accepted, but I consider git a complete waste of my time and have zero interest in learning to use it. Plus, while I admire everyone's willingness to consider a VCS that isn't Haskell-based, I have to admit that there's a Haskell partisan in me. And there are real advantages to being a tight-knit community. If the GHC maintainers go to the Darcs maintainers and say We absolutely need feature X or we will have to stop using you, the Darcs maintainers are likely to say It'll be tough but we'll find a way to do it. But we aren't by any means the biggest project using Git, so the Git maintainers would be likely to say That's nice, keep in touch. Obligatory disclaimer - I've never written any code actually in GHC, although I have used the API (I am the author of direct-plugins). But I frequently read its code to clarify how things work, and I do expect that it's a near-certainty that I'll be hacking GHC itself at some point in the future. -- Dan Knapp An infallible method of conciliating a tiger is to allow oneself to be devoured. (Konrad Adenauer) ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: RFC: migrating to git
I just noticed that the discussion has been concluded and I was replying to an old thread. I apologize for the noise. On Wed, Feb 9, 2011 at 6:56 PM, Dan Knapp dan...@gmail.com wrote: In my one serious attempt to use git for one of my own projects, some seemingly-innocuous operation deleted a file on me and I lost a couple hours of work. I agree with the people who have said that git's documentation and semantics are highly confusing, moreso than darcs's. For example, what does it mean to stage a commit? Why is there an entire GUI window for this presumably-important action, and why do things I think I've committed not appear in the change history or mysteriously reverse themselves? If ghc went to git, it wouldn't make me less likely to contribute, but I would do so by checking everything into a local darcs repo and using that to track my own changes, then letting somebody else do the work of getting them into git! Which probably would reduce the likelihood of my patch being accepted, but I consider git a complete waste of my time and have zero interest in learning to use it. Plus, while I admire everyone's willingness to consider a VCS that isn't Haskell-based, I have to admit that there's a Haskell partisan in me. And there are real advantages to being a tight-knit community. If the GHC maintainers go to the Darcs maintainers and say We absolutely need feature X or we will have to stop using you, the Darcs maintainers are likely to say It'll be tough but we'll find a way to do it. But we aren't by any means the biggest project using Git, so the Git maintainers would be likely to say That's nice, keep in touch. Obligatory disclaimer - I've never written any code actually in GHC, although I have used the API (I am the author of direct-plugins). But I frequently read its code to clarify how things work, and I do expect that it's a near-certainty that I'll be hacking GHC itself at some point in the future. -- Dan Knapp An infallible method of conciliating a tiger is to allow oneself to be devoured. (Konrad Adenauer) -- Dan Knapp An infallible method of conciliating a tiger is to allow oneself to be devoured. (Konrad Adenauer) ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: my RULES don't fire
Why don't the rules fire, Because the 'match' is at the wrong type. This was the correct hint, thanks! what can I change such that they do, Type signatures. Initially, I thought that just leaving out the polymorphic signature should fix the problem. But I think it cannot be fixed by changing type signatures only because once the type of `g` in the rule is fixed, the rule is no longer type correct! To overcome this, I have defined gen :: (forall m . Monoid m = (a - m) - b - m) - b - [a] gen g = g single {-# NOINLINE gen #-} and changed the rules to {-# RULES monoid fusion pointfree forall f (g :: forall m . Monoid m = (a - m) - b - m) . fold f . gen g = g f; monoid fusion pointed forall f (g :: forall m . Monoid m = (a - m) - b - m) b . fold f (gen g b) = g f b; #-} and now they fire. Seems a bit roundabout but I don't see how to avoid this indirection. and what to get rid of the warning for the second rule (which I think is the one I should use)? I'll let that for somebody else. My new rules don't cause this warning. I'm still interested in what the warning meant, although my code does not depend on an answer anymore. Probably because, GHC inlines function composition in the first line of main = do print ((fold id . gen idGen) [[()]]) print (fold id (gen idGen [[()]])) the pointed rule fires twice if I remove the point-free one. Does it make sense to keep the point-free rule just in case that `fold f . gen g` is passed to a higher-order function and does not get an argument after inlining? Sebastian ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Deriviable type classes
Simon Peyton-Jones wrote: Generic Defaults... will replace... the Derivable type classes stuff... in GHC 7.2 or 7.4... Please yell if you are a secret user of derivable type classes, so this change would discombobulate you. Could you give us a preview of the parts of the syntax spectrum that will be gobbled up by this? That is a way that the change could affect even people who are not using the current generics. For example, the old generics knocked a very nice bracket out of consideration for TH syntax. It also blessed the names of certain magical constructors, which can be good to know about even if the magic doesn't leak out of the generics world. Thanks, Yitz ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Dictionaries and full laziness transformation
I've been using ghc-7.1.20110125 and it does indeed help a great deal. I've tried compiling several problematic functions and in most cases the problem is gone. However, in one of my test cases the closures are still being constructed: let { lvl8_s1S8 :: [Data.Iteratee.Base.Iteratee s_aXZ m_aXY a_aY1] - Data.Iteratee.Base.Iteratee s_aXZ m_aXY () [LclId, Str=DmdType] lvl8_s1S8 = EnumSequenceTest.enumSequence_ @ m_aXY @ s_aXZ @ el_aY0 @ a_aY1 $dMonad_s1Q4 $dListLike_s1Q0 $dNullable_s1PV } in The code for enumSequence_ is included in the attachment. There are two versions: * enumSequence-bad.hs is the original code * enumSequence-good.hs includes a fix suggested by Akio When compiled with ghc-7.1.20110125 and -O2 [1] it uses a lot of memory: ./enumSequence-main +RTS -s 1 1 0 22,787,568,816 bytes allocated in the heap 1,455,499,400 bytes copied during GC 260,651,512 bytes maximum residency (10 sample(s)) 14,457,544 bytes maximum slop 530 MB total memory in use (0 MB lost due to fragmentation) Generation 0: 43936 collections, 0 parallel, 1.58s, 1.57s elapsed Generation 1:10 collections, 0 parallel, 1.05s, 1.05s elapsed INIT time0.00s ( 0.00s elapsed) MUT time4.64s ( 4.66s elapsed) GCtime2.63s ( 2.62s elapsed) EXIT time0.00s ( 0.00s elapsed) Total time7.27s ( 7.28s elapsed) %GC time 36.1% (36.0% elapsed) Alloc rate4,905,159,063 bytes per MUT second Productivity 63.8% of total user, 63.8% of total elapsed while compiling with -O2 and -fno-full-laziness or -O0 reverts memory usage back to constant: ./enumSequence-main +RTS -s 1 1 0 22,493,819,416 bytes allocated in the heap 578,891,112 bytes copied during GC 46,696 bytes maximum residency (1 sample(s)) 19,928 bytes maximum slop 1 MB total memory in use (0 MB lost due to fragmentation) Generation 0: 43335 collections, 0 parallel, 1.07s, 1.07s elapsed Generation 1: 1 collections, 0 parallel, 0.00s, 0.00s elapsed INIT time0.00s ( 0.00s elapsed) MUT time4.53s ( 4.55s elapsed) GCtime1.07s ( 1.07s elapsed) EXIT time0.00s ( 0.00s elapsed) Total time5.60s ( 5.62s elapsed) %GC time 19.2% (19.0% elapsed) Alloc rate4,966,355,161 bytes per MUT second Productivity 80.8% of total user, 80.5% of total elapsed -- Maciej [1] ghc --make -rtsopts -fforce-recomp -O2 enumSequence-bad.hs enumSequence-main.hs [2] ghc --make -rtsopts -fforce-recomp -O2 -fno-full-laziness enumSequence-bad.hs enumSequence-main.hs On Thu, Feb 10, 2011 at 2:00 AM, Simon Peyton-Jones simo...@microsoft.com wrote: In general it's quite hard to solve this problem without risking losing sharing. However in this case I added a simple arity analyser after the 7.0.1 release which solves the problem. It'll be in 7.0.2. Try with HEAD and check it does what you expect. Simon | -Original Message- | From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell- | users-boun...@haskell.org] On Behalf Of Akio Takano | Sent: 07 February 2011 04:10 | To: glasgow-haskell-users@haskell.org | Subject: Dictionaries and full laziness transformation | | Hi, | | I'm using GHC 7.0.1. I found that recursive overloaded functions tend | to leak memory when compiled with full-laziness optimization on. Here | is a simple case. | | -- TestSub.hs | {-# LANGUAGE BangPatterns #-} | module TestSub where | | {-# NOINLINE factorial #-} | factorial :: (Num a) = a - a - a | factorial !n !acc = if n == 0 then acc else factorial (n - 1) (acc * n) | | -- main.hs | import TestSub | | factorial1 :: Int - Int - Int | factorial1 = factorial | | main = do | n - readLn | print $ factorial1 n 1 | | main | | This program should run in constant space, and compiled with -O0 or | -O2 -fno-full-laziness, it does. However with -O2, it takes a linear | amount of memory. The core for factorial looks like this: | | TestSub.factorial = | \ (@ a_ajm) ($dNum_slz :: GHC.Num.Num a_ajm) - | let { | a_slA :: GHC.Classes.Eq a_ajm | [LclId] | a_slA = GHC.Num.$p1Num @ a_ajm $dNum_slz } in | let { | lvl2_slC :: a_ajm - a_ajm - a_ajm | [LclId] | lvl2_slC = TestSub.factorial @ a_ajm $dNum_slz } in | ... | | The problem is that lvl2_slC closure is created whenever factorial is | applied to a Num dictionary, and kept alive until that application is | GCed. In this program it never happens, because an application to the | Num Int dictionary is referred to by the factorial1 CAF, and it | recursively keeps the whole chain of closures alive. | | I know that full laziness transformation *sometimes* causes a space | leak, but this looks like a bad result