Daniel, >This means *when meanOver2 is evaluated*, then evaluate (mean as). >Binding it in a let is lazy, so it won't be evaluated until it's needed >(for printing in this case). >Also note that (mean as) is a Double, so deepseq is just seq in this case >(but I suppose this is just a boiled down example and you also want to time >computations with results where deepseq does strictly more than seq).
Thanks for the help, I think I understand now. This is indeed a boiled down example. I have some data that I am trying to compute in parallel, and I want to control how much evaluation to force. To do this, I was trying to use NFData and deepseq, since I thought bang patterns were a little clunky (but maybe they are less clunky than forcing evaluations with seq and deepseqs). Are there best practices for keeping track of which variables are bound where, when writing a complex program? >There are two standard ways to achieve what you want, >1. > let meanOver2 = ... > end <- meanOver2 `deepseq` getCurrentTime >2. put {-# LANGUAGE BangPatterns #-} at the top of the file and write > let !meanOver2 = ... > end <- getCurrentTime >The bang on meanOver2 means "evaluate this expression now (to weak head >normal form, i.e. to the outermost constructor)". Sometimes for me, whnf is not quite enough. For example, if I have a newtype P (with type constructor P) that is a for Map M Int. Is NFData and deepseq the way to do this, or should I be trying to implement my own Strategy along the lines of rwhnf in Control.Parallel.Strategies? >Another thing, for timing computations, wall-clock time is not appropriate, >better use >System.CPUTime.getCPUTime >to get only the CPU-time the process took, and not also what your browser >or whatever used in the meantime. Thanks for the tip. Frank > On Thu, Jun 24, 2010 at 9:38 PM, Daniel Fischer <daniel.is.fisc...@web.de> > wrote: >> >> On Friday 25 June 2010 02:57:31, Frank Moore wrote: >> > Hello Haskellers, >> > >> > I am new to programming in Haskell and I am having trouble understanding >> > exactly when statements become evaluated. My goal is to try and measure >> > how long a computation takes without having to use a show function. The >> > code I am trying to use is below (taken in part from RWH chapter 25) >> > >> > ---------------------------------- >> > import Data.List (foldl') >> > import Data.Time.Clock (diffUTCTime, getCurrentTime) >> > import Control.DeepSeq (deepseq) >> > >> > mean :: [Double] -> Double >> > mean xs = s / fromIntegral n where >> > (n,s) = foldl' k (0,0) xs >> > k (n,s) x = n `seq` s `seq` (n+1,s+x) >> > >> > main = do >> > let as = [1..1e7] :: [Double] >> > start <- getCurrentTime >> > let meanOver2 = deepseq (mean as) `seq` (mean as) / fromIntegral 2 >> >> This means *when meanOver2 is evaluated*, then evaluate (mean as). >> Binding it in a let is lazy, so it won't be evaluated until it's needed >> (for printing in this case). >> Also note that (mean as) is a Double, so deepseq is just seq in this case >> (but I suppose this is just a boiled down example and you also want to time >> computations with results where deepseq does strictly more than seq). >> >> There are two standard ways to achieve what you want, >> >> 1. >> let meanOver2 = ... >> end <- meanOver2 `deepseq` getCurrentTime >> >> 2. put {-# LANGUAGE BangPatterns #-} at the top of the file and write >> >> let !meanOver2 = ... >> end <- getCurrentTime >> >> The bang on meanOver2 means "evaluate this expression now (to weak head >> normal form, i.e. to the outermost constructor)". >> >> > end <- getCurrentTime >> > putStrLn (show (end `diffUTCTime` start)) >> > putStrLn (show meanOver2) >> > ------------------------------------- >> >> Another thing, for timing computations, wall-clock time is not appropriate, >> better use >> >> System.CPUTime.getCPUTime >> >> to get only the CPU-time the process took, and not also what your browser >> or whatever used in the meantime. >> >> > >> > My understanding of deepseq was that it evaluates (mean as) completely >> > before continuing, and then the show would not take any time, but >> >> No, it evaluates (mean as) completely *when meanOver2 is demanded*, not >> before. >> >> > instead all the time is spent in the show meanOver2 function. I feel >> > like I am missing something fundamental here. Any suggestions? Thanks >> > for your help. >> > >> > Frank >> > > > > -- > Dr. W. Frank Moore > H. C. Wang Assistant Professor > Department of Mathematics, Cornell University > 310 Malott Hall, Ithaca NY 14853-4201, USA > > Office: Malott 587, Phone: +1 607 255 4030 > Email: frankmo...@math.cornell.edu -- Dr. W. Frank Moore H. C. Wang Assistant Professor Department of Mathematics, Cornell University 310 Malott Hall, Ithaca NY 14853-4201, USA Office: Malott 587, Phone: +1 607 255 4030 Email: frankmo...@math.cornell.edu _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe