
Programming for Rosetta Codes task http://www.rosettacode.org/wiki/Probabilistic_Choice I observed a remarkable (that's to say: for me) difference in timing using lambda function in the one case and point free in the other. Timing was measured in GHCi. Compiled there's no difference! Using lambda ============ ... labels = ["aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth" ] piv n = take n . flip (++) (repeat ' ') main = do g <- newStdGen let rs :: [Float] rs = take 1000000 $ randomRs(0,1) g ps, sps :: [Float] ps = ap (++) (return. (-) 1 .sum) $ map recip [5.0..11.0] sps = scanl1 (+) ps ix = map ((/1000000.0).fromIntegral.length). group.sort $ map (\x -> fromJust $ findIndex not $ map (x>) sps) rs mapM_ (\(l,s,c)-> putStrLn $ (piv 6 l) ++ " " ++ (piv 12 $ show $ s) ++ " " ++ ((piv 12 $ show $ c) )) $ zip3 labels ps ix Using point free ================ replace $ map (\x -> fromJust $ findIndex not $ map (x>) sps) rs by $ map (fromJust. findIndex not. flip map sps. (>)) rs lambda: ======= *Main> main ... (18.24 secs, 2524489600 bytes) point free: =========== *Main> main ... (12.15 secs, 2470893260 bytes) Should I program using point free as much as possible? :-) Thanks =@@i

Hello Aai, Thursday, December 25, 2008, 11:45:33 AM, you wrote:
remarkable (that's to say: for me) difference in timing using lambda function in the one case and point free in the other. Timing was measured in GHCi. Compiled there's no difference!
compiler optimizes program, replacing slower version with faster one. ghci executes code exactly -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hi Bulat, That I (can) understand, but of course the main question is: is point free in (some/several/all) cases faster than the more readable lambda construction? That's to say when executed in GHCi. I noticed this behavior before (pity I haven't other examples at hand). In prog. lang. J ( http://www.jsoftware.com/index.html ) I see the same behavior difference with tacit (like point free) and explicit programming: tacit being faster in several (not all) occasions. Thanks =@@i Bulat Ziganshin schreef:
compiler optimizes program, replacing slower version with faster one. ghci executes code exactly

Aai пишет:
Hi Bulat,
That I (can) understand, but of course the main question is: is point free in (some/several/all) cases faster than the more readable lambda construction? That's to say when executed in GHCi. I noticed this behavior before (pity I haven't other examples at hand). In prog. lang. J ( http://www.jsoftware.com/index.html ) I see the same behavior difference with tacit (like point free) and explicit programming: tacit being faster in several (not all) occasions.
You should write cleanest code. Optimize only when absolutely necessary (and in this case you'll definetly will use a compiled version instead of interpreted). -- WBR, Max Vasin.

Compiled timing (point free version: doesn't matter though as mentioned by Bulat): ..> ghc -O2 ./../Puzzels/Rosetta/probabilistic_choice.hs -o proba ..> time ./proba ... real 0m9.975s user 0m9.765s sys 0m0.212s GHCi: (12.26 secs, 2470869600 bytes) So about 20 pct faster than interpreted point free: not world shaking. May be there's a compile optimization that I'm not aware of. Thanks =@@i Max Vasin schreef:
Aai пишет:
Hi Bulat,
That I (can) understand, but of course the main question is: is point free in (some/several/all) cases faster than the more readable lambda construction? That's to say when executed in GHCi. I noticed this behavior before (pity I haven't other examples at hand). In prog. lang. J ( http://www.jsoftware.com/index.html ) I see the same behavior difference with tacit (like point free) and explicit programming: tacit being faster in several (not all) occasions.
You should write cleanest code. Optimize only when absolutely necessary (and in this case you'll definetly will use a compiled version instead of interpreted).
-- WBR, Max Vasin.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Aai wrote:
Hi Bulat,
That I (can) understand, but of course the main question is: is point free in (some/several/all) cases faster than the more readable lambda construction? That's to say when executed in GHCi. I noticed this behavior before (pity I haven't other examples at hand). In prog. lang. J ( http://www.jsoftware.com/index.html ) I see the same behavior difference with tacit (like point free) and explicit programming: tacit being faster in several (not all) occasions.
In general point-free will be marginally faster because: foo = \x -> ... defines foo as a constant, whereas: foo x = ... defines (foo x) to be constant for a given x. This subtle distinction makes for small differences in the runtime which add up eventually. The performance difference here is what's at stake when people talk about "the monomorphism restriction". Without a type signature to indicate otherwise, the point-free/lambda version is forced to be monomorphic because it "looks like a constant". Whereas the second version could be hiding the fact that we can't do unboxing of x, or that we need to locate type-class dictionaries based on the type of x, etc. All that said, these differences are things which should only matter in GHCi and should never affect compiled code. GHC does a lot of analysis and does eta-expansion/-reduction in order to make the compiled code optimal. If you ever notice a difference in performance from compiled code, the GHC developers would love to hear about it I'm sure. I'm less familiar with Hugs' optimizations, but you probably shouldn't notice any difference there either. In any case, you should always use whichever style is clearest. A few microseconds here or there isn't worth the extra minutes it takes to understand your own code six months from now. (And changing your algorithms or datastructures will overshadow any micro-optimizations like this anyways.) -- Live well, ~wren
participants (4)
-
Aai
-
Bulat Ziganshin
-
Max Vasin
-
wren ng thornton