# shared local definitions

4 messages
Open this post in threaded view
|

## shared local definitions

 Hi all, I have a question about optimization of shared values in local definitions. I frequently use this scheme: fun a b c d x = r where     q = costly computation depending only on a, b, c, and d     r = depends only on q and x g1 = fun 1 2 3 4 g2 = fun 5 4 2 7 (etc.) When I compute (using ghc -O) things like map g1 [1 .. 1000] the common q is evaluated only once, which is very nice. But the problem is that in some strange cases this kind of optimization is not applied, and the same q is evaluated 1000 times. Curiously, this happens if I add just: module Main where to one of my programs. Optimization is also lost if in the same program I use two partially applied functions: map g1 [1 .. 1000] map g2 [1 .. 1000] And in some cases optimization is only applied if the local definition is "easy" enough. For example: --------------------------------------------------- fun1 :: Int -> Int -> Int fun1 a x = q*x where     q = {-# SCC "easy" #-} a+1+a^2   -- OK   fun2 :: Int -> Int -> Int fun2 a x = q*x where     q = {-# SCC "hard" #-} a+1+a^2 +a^3+(2*a)  -- NO fun3 :: Int -> Int -> Int fun3 a x = r where     q = local a     r = q*x     local u = {-# SCC "local easy" #-} u+1  -- OK   fun4 :: Int -> Int -> Int fun4 a x = r where     q = local a     r = q*x     local u = {-# SCC "local hard" #-} u+1+u^2  -- NO   test h = print \$ sum \$ map h [1 .. 100]           main = do     test (fun1 3)     test (fun2 3)     test (fun3 3)     test (fun4 3) -------------------------------------------------- COST CENTRE              MODULE         no.    entries MAIN                     MAIN            1           0  main                    Main          154         101   fun4                   Main          166         300    local hard            Main          167         100   NO   fun3                   Main          163         100     fun2                   Main          161         100        hard                  Main          162         100   NO   fun1                   Main          157         100             test                   Main          155           4  CAF                     Main          148           6   fun4                   Main          168           0   main                   Main          158           0    fun3                  Main          164           1     local easy           Main          165           1   OK    fun1                  Main          159           0     easy                 Main          160           1   OK   test                   Main          156           0  CAF                     System.IO     103           1  CAF                     GHC.Handle    101           3 ------------------------------------------------------------ Where can I find information about this topic? I have made some searches but probably using wrong keywords. Should I use some individual optimization flags? Thanks, Alberto _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe
Open this post in threaded view
|

## Re: shared local definitions

 On Thu, 2006-05-18 at 11:00 +0200, Alberto Ruiz wrote: > When I compute (using ghc -O) things like > > map g1 [1 .. 1000] > > the common q is evaluated only once, which is very nice. But the problem > is that in some strange cases this kind of optimization is not applied, and > the same q is evaluated 1000 times. Curiously, this happens if I add just: > > module Main where This is explained by how it affects what functions your module exports. When you have no module header, the default is that it is the Main module and that nothing other than the function main is exported. When you add "module Main where" then everything in the module is exported. The compiler can often optimise things better if it knows that they do not need to be exported. For example if a function is not exported and only used once then the compiler will probably decide that it is beneficial to inline. If it needs to keep a copy of the function to export from the module then it may decide that the code duplication is not worth it and not inline. Duncan _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe