
Hi, my following code should show time before executing listeprem, then time after execution. import System.Time gettime :: IO ClockTime gettime = getClockTime main=do t1d <- gettime let t1=last (listeprem 5000) t1f <- gettime putStrLn ("Methode 1 : " ++ show t1d) putStrLn (" " ++ show t1) putStrLn (" " ++ show t1f) Looking at the screen, t1d is displayed then, after a few seconds, t1 and t1f. But, t1d and t1f are equal. It seems like if t1d and t1f where calculated at start of procedure, before we need calculating t1 for putStrLn. How can i have t1f evaluated after t1, so i can calculate time elapsed for calculation of t1? Thanks, Didier

Am Samstag 13 März 2010 21:20:58 schrieb legajid:
Hi, my following code should show time before executing listeprem, then time after execution.
import System.Time gettime :: IO ClockTime gettime = getClockTime
main=do t1d <- gettime
This gets the time, now.
let t1=last (listeprem 5000)
This doesn't do the calculation, it only creates a thunk what to calculate should t1 be demanded, takes a few nanoseconds
t1f <- gettime
This gets the time, a few nanoseconds later
putStrLn ("Methode 1 : " ++ show t1d) putStrLn (" " ++ show t1)
Now t1 is demanded, and only now it's calculated.
putStrLn (" " ++ show t1f)
Looking at the screen, t1d is displayed then, after a few seconds, t1 and t1f. But, t1d and t1f are equal. It seems like if t1d and t1f where calculated at start of procedure, before we need calculating t1 for putStrLn.
Exactly.
How can i have t1f evaluated after t1, so i can calculate time elapsed for calculation of t1?
Depends on what sort of value t1 is. If it's a simple value like an Integer (as I think it is here, derniere nombre premier avant 5000, 5000-th prime?), {-# LANGUAGE BangPatterns #-} ... let !t1 = last (listeprem 5000) t1f <- gettime or let t1 = last (listeprem 5000) t1f <- t1 `seq` gettime will do. For small values, printing takes negligible time, so t1d <- gettime putStrLn (" " ++ show t1f) t1f <- gettime is another option. But getClockTime isn't particularly exact, I'd suggest using System.CPUTime.getCPUTime
Thanks, Didier

Sorry Daniel, i've seen your answer just after posting my reply. But i can't write !t1f <- gettime, nor t1f <- !gettime; because it's an IO ? Your method is a good help form me. Thanks, Didier Daniel Fischer a écrit :
Am Samstag 13 März 2010 21:20:58 schrieb legajid:
Hi, my following code should show time before executing listeprem, then time after execution.
import System.Time gettime :: IO ClockTime gettime = getClockTime
main=do t1d <- gettime
This gets the time, now.
let t1=last (listeprem 5000)
This doesn't do the calculation, it only creates a thunk what to calculate should t1 be demanded, takes a few nanoseconds
t1f <- gettime
This gets the time, a few nanoseconds later
putStrLn ("Methode 1 : " ++ show t1d) putStrLn (" " ++ show t1)
Now t1 is demanded, and only now it's calculated.
putStrLn (" " ++ show t1f)
Looking at the screen, t1d is displayed then, after a few seconds, t1 and t1f. But, t1d and t1f are equal. It seems like if t1d and t1f where calculated at start of procedure, before we need calculating t1 for putStrLn.
Exactly.
How can i have t1f evaluated after t1, so i can calculate time elapsed for calculation of t1?
Depends on what sort of value t1 is. If it's a simple value like an Integer (as I think it is here, derniere nombre premier avant 5000, 5000-th prime?),
{-# LANGUAGE BangPatterns #-} ... let !t1 = last (listeprem 5000) t1f <- gettime
or
let t1 = last (listeprem 5000) t1f <- t1 `seq` gettime
will do. For small values, printing takes negligible time, so
t1d <- gettime putStrLn (" " ++ show t1f) t1f <- gettime
is another option. But getClockTime isn't particularly exact, I'd suggest using System.CPUTime.getCPUTime
Thanks, Didier

Am Samstag 13 März 2010 22:02:41 schrieb legajid:
Sorry Daniel, i've seen your answer just after posting my reply.
Thought so. Happens to me often enough :)
But i can't write !t1f <- gettime,
You can, and it's much like let !t1 = ... for the pure calculation, it evaluates t1f to the outermost constructor. If deeper evaluation is needed, like for pure values, you have to use the appropriate forcing strategy. !a <- mx is less important for IO than for other monads, though, since IO imposes a fair amount of sequencing. In particular, the sequencing of IO makes !t1f <- gettime superfluous, since all that could be delayed in gettime is the transformation of the timestamp retrieved from the system clock to the ClockTime datatype, the timestamp is retrieved at the exact point in the IO-sequence.
nor t1f <- !gettime;
I'm not sure whether you can write that, but it wouldn't be what you want anyway. If that's legal BangPattern syntax, it says "evaluate gettime to the outermost constructor", which is far less than we need to evaluate gettime to bind its result to a name.
because it's an IO ? Your method is a good help form me.
Thanks, Didier

I tried !t1f <- gettime and i got an error message : premier.hs:92:1: Illegal bang-pattern (use -XBangPatterns) Failed, modules loaded: none. t1f <- !gettime gives : premier.hs:92:8: parse error on input `!' Failed, modules loaded: none. Daniel Fischer a écrit :
Am Samstag 13 März 2010 22:02:41 schrieb legajid:
Sorry Daniel, i've seen your answer just after posting my reply.
Thought so. Happens to me often enough :)
But i can't write !t1f <- gettime,
You can, and it's much like
let !t1 = ...
for the pure calculation, it evaluates t1f to the outermost constructor. If deeper evaluation is needed, like for pure values, you have to use the appropriate forcing strategy.
!a <- mx
is less important for IO than for other monads, though, since IO imposes a fair amount of sequencing. In particular, the sequencing of IO makes
!t1f <- gettime
superfluous, since all that could be delayed in gettime is the transformation of the timestamp retrieved from the system clock to the ClockTime datatype, the timestamp is retrieved at the exact point in the IO-sequence.
nor t1f <- !gettime;
I'm not sure whether you can write that, but it wouldn't be what you want anyway. If that's legal BangPattern syntax, it says "evaluate gettime to the outermost constructor", which is far less than we need to evaluate gettime to bind its result to a name.
because it's an IO ? Your method is a good help form me.
Thanks, Didier

Am Samstag 13 März 2010 23:09:48 schrieb legajid:
I tried
!t1f <- gettime
and i got an error message : premier.hs:92:1: Illegal bang-pattern (use -XBangPatterns) Failed, modules loaded: none.
t1f <- !gettime gives : premier.hs:92:8: parse error on input `!' Failed, modules loaded: none.
Ah yes, you must tell GHC that you want to use bang-patterns, best with a {-# LANGUAGE BangPatterns #-} pragma right at the top of the file (you can too easily forget to pass -XBangPatterns on the command ine).

After a few efforts, i've understood my mistake. I now write : t1d <- gettime putStrLn ("Methode 1 : " ++ show t1d) let t1=last (listeprem 5000) putStrLn (" " ++ show t1) t1f <- gettime putStrLn (" " ++ show t1f) and that's ok. What i feel shocking is having io code mixed within calculation code. I think it's possible to force calculation of t1d, t1 and t1f before (or without) displaying their values (i just want t1f - t1d). But how to make it ? Thanks, Didier . legajid a écrit :
Hi, my following code should show time before executing listeprem, then time after execution.
import System.Time gettime :: IO ClockTime gettime = getClockTime
main=do t1d <- gettime let t1=last (listeprem 5000) t1f <- gettime putStrLn ("Methode 1 : " ++ show t1d) putStrLn (" " ++ show t1) putStrLn (" " ++ show t1f)
Looking at the screen, t1d is displayed then, after a few seconds, t1 and t1f. But, t1d and t1f are equal. It seems like if t1d and t1f where calculated at start of procedure, before we need calculating t1 for putStrLn. How can i have t1f evaluated after t1, so i can calculate time elapsed for calculation of t1?
Thanks, Didier
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Am Samstag 13 März 2010 21:42:12 schrieb legajid:
After a few efforts, i've understood my mistake. I now write : t1d <- gettime putStrLn ("Methode 1 : " ++ show t1d) let t1=last (listeprem 5000) putStrLn (" " ++ show t1) t1f <- gettime putStrLn (" " ++ show t1f)
and that's ok.
What i feel shocking is having io code mixed within calculation code.
Right, that's not so good.
I think it's possible to force calculation of t1d, t1 and t1f before (or without) displaying their values (i just want t1f - t1d). But how to make it ?
Depends on the types. Often a bang-pattern or a `seq` is enough, for other types, you might want to look at Control.DeepSeq and Control.Parallel.Strategies. NFData, rnf, deepseq, using, demanding, ... may help you. For lists, sometimes (length list) `seq` whatever is enough, without needing strategies.
Thanks, Didier

On Sat, 2010-03-13 at 21:20 +0100, legajid wrote:
Hi, my following code should show time before executing listeprem, then time after execution.
import System.Time import Control.Exception
gettime :: IO ClockTime gettime = getClockTime
main=do t1d <- gettime let t1=last (listeprem 5000)
evaluate t1
t1f <- gettime putStrLn ("Methode 1 : " ++ show t1d) putStrLn (" " ++ show t1) putStrLn (" " ++ show t1f)
Looking at the screen, t1d is displayed then, after a few seconds, t1 and t1f. But, t1d and t1f are equal. It seems like if t1d and t1f where calculated at start of procedure, before we need calculating t1 for putStrLn. How can i have t1f evaluated after t1, so i can calculate time elapsed for calculation of t1?
Thanks, Didier
Haskell calculates the expression when it needs. So let t1 = last (listeprem 5000) Means rather 't1 is expression ....' then calculate .... and save result in t1. evaluate is a nice function that forces the evaluation. Regards
participants (3)
-
Daniel Fischer
-
legajid
-
Maciej Piechotka