How to display a time difference?

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Colin Paul Adams
The code of the following routine is intended to indicate how long it
takes for the computer to make a move. However the time is printed (as
very close to zero) long before the move is made.

I must be missing something about sequencing actions in the IO monad.

play_move :: IORef Game_state -> IO ()
play_move game_state_ior = do
  (_, state, _) <- readIORef game_state_ior  
  putStr "Playing AI: "
  start_time <- getCurrentTime
  let move = recommended_move state
  modifyIORef game_state_ior (update_interactive_from_move move)
  end_time <- getCurrentTime
  putStrLn $ show $ (diffUTCTime end_time start_time)

--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Yitzchak Gale
Colin Paul Adams wrote:
> The code of the following routine is intended to indicate how long it
> takes for the computer to make a move. However the time is printed (as
> very close to zero) long before the move is made.

You are writing a thunk to the IORef. It only gets computed
later on when you read the value.

Try using:

> readIORef game_state_ior >>=
>    evaluate . update_interactive_from_move move >>=
>    writeIORef game_state_ior

evaluate is in Control.Exception.

-Yitz
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Colin Paul Adams
>>>>> "Yitzchak" == Yitzchak Gale <[hidden email]> writes:

    Yitzchak> Colin Paul Adams wrote:
    >> The code of the following routine is intended to indicate how
    >> long it takes for the computer to make a move. However the time
    >> is printed (as very close to zero) long before the move is
    >> made.

    Yitzchak> You are writing a thunk to the IORef. It only gets
    Yitzchak> computed later on when you read the value.

    Yitzchak> Try using:

    >> readIORef game_state_ior >>= evaluate
    >> . update_interactive_from_move move >>= writeIORef
    >> game_state_ior

    Yitzchak> evaluate is in Control.Exception.

Still no joy with:

play_move :: IORef Game_state -> IO ()
play_move game_state_ior = do
  (_, state, _) <- readIORef game_state_ior  
  putStr "Playing AI: "
  start_time <- getCurrentTime
  let move = recommended_move state
  readIORef game_state_ior >>=
    evaluate . update_interactive_from_move move >>=
             writeIORef game_state_ior
  end_time <- getCurrentTime
  putStrLn $ show $ (diffUTCTime end_time start_time)


--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Sean Lee-4
Hi Colin

The following code probably would do what I wanted to do.

play_move :: IORef Game_state -> IO ()
play_move game_state_ior = do
 (_, state, _) <- readIORef game_state_ior
 putStr "Playing AI: "
 start_time <- getCurrentTime
 let move = recommended_move state
 end_time <- move `seq` (modifyIORef game_state_ior $!
update_interactive_from_move move) `seq` getCurrentTime
 putStrLn $ show $ (diffUTCTime end_time start_time)

Due to the non-strictness of Haskell, the evaluation of the
expressions between start_time and end_time is deferred until there is
a need.
By using `seq` and ($!), the strictness can be forced.


Sean

On Wed, Mar 18, 2009 at 9:28 PM, Colin Paul Adams
<[hidden email]> wrote:

>>>>>> "Yitzchak" == Yitzchak Gale <[hidden email]> writes:
>
> ? ?Yitzchak> Colin Paul Adams wrote:
> ? ?>> The code of the following routine is intended to indicate how
> ? ?>> long it takes for the computer to make a move. However the time
> ? ?>> is printed (as very close to zero) long before the move is
> ? ?>> made.
>
> ? ?Yitzchak> You are writing a thunk to the IORef. It only gets
> ? ?Yitzchak> computed later on when you read the value.
>
> ? ?Yitzchak> Try using:
>
> ? ?>> readIORef game_state_ior >>= evaluate
> ? ?>> . update_interactive_from_move move >>= writeIORef
> ? ?>> game_state_ior
>
> ? ?Yitzchak> evaluate is in Control.Exception.
>
> Still no joy with:
>
> play_move :: IORef Game_state -> IO ()
> play_move game_state_ior = do
> ?(_, state, _) <- readIORef game_state_ior
> ?putStr "Playing AI: "
> ?start_time <- getCurrentTime
> ?let move = recommended_move state
> ?readIORef game_state_ior >>=
> ? ?evaluate . update_interactive_from_move move >>=
> ? ? ? ? ? ? writeIORef game_state_ior
> ?end_time <- getCurrentTime
> ?putStrLn $ show $ (diffUTCTime end_time start_time)
>
>
> --
> Colin Adams
> Preston Lancashire
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners
>



--
Sean Lee
PhD Student
Programming Language and Systems Research Group
School of Computer Science and Engineering
University of New South Wales
http://www.cse.unsw.edu.au/~seanl
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Daniel Fischer-4
In reply to this post by Colin Paul Adams
Am Mittwoch, 18. M?rz 2009 11:28 schrieb Colin Paul Adams:

> >>>>> "Yitzchak" == Yitzchak Gale <[hidden email]> writes:
>
>     Yitzchak> Colin Paul Adams wrote:
>     >> The code of the following routine is intended to indicate how
>     >> long it takes for the computer to make a move. However the time
>     >> is printed (as very close to zero) long before the move is
>     >> made.
>
>     Yitzchak> You are writing a thunk to the IORef. It only gets
>     Yitzchak> computed later on when you read the value.
>
>     Yitzchak> Try using:
>     >> readIORef game_state_ior >>= evaluate
>     >> . update_interactive_from_move move >>= writeIORef
>     >> game_state_ior
>
>     Yitzchak> evaluate is in Control.Exception.
>
> Still no joy with:
>
> play_move :: IORef Game_state -> IO ()
> play_move game_state_ior = do
>   (_, state, _) <- readIORef game_state_ior
>   putStr "Playing AI: "
>   start_time <- getCurrentTime
>   let move = recommended_move state
>   readIORef game_state_ior >>=
>     evaluate . update_interactive_from_move move >>=
>              writeIORef game_state_ior
>   end_time <- getCurrentTime
>   putStrLn $ show $ (diffUTCTime end_time start_time)

You would have to completely evaluate move. Depending on what type move is,
that might require much more than what seq or evaluate do.

Perhaps

import Control.Parallel.Strategies

let move = ...
(rnf move) `seq` mofifyIORef (...)

?

Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Colin Paul Adams
In reply to this post by Sean Lee-4
>>>>> "Sean" == Sean Lee <[hidden email]> writes:

    Sean> Hi Colin The following code probably would do what I wanted
    Sean> to do.

    Sean> play_move :: IORef Game_state -> IO () play_move
    Sean> game_state_ior = do (_, state, _) <- readIORef
    Sean> game_state_ior putStr "Playing AI: " start_time <-
    Sean> getCurrentTime let move = recommended_move state end_time <-
    Sean> move `seq` (modifyIORef game_state_ior $!
    Sean> update_interactive_from_move move) `seq` getCurrentTime
    Sean> putStrLn $ show $ (diffUTCTime end_time start_time)

    Sean> Due to the non-strictness of Haskell, the evaluation of the
    Sean> expressions between start_time and end_time is deferred
    Sean> until there is a need.  By using `seq` and ($!), the
    Sean> strictness can be forced.

It certainly causes a time delay, and a non-zero time is printed, but
the state doesn't get modified correctly now.

??

I will ponder Daniel's suggestion.
--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Sean Lee-4
In reply to this post by Sean Lee-4
> The following code probably would do what I wanted to do.

I mean "what you wanted to do." :)


--
Sean Lee
PhD Student
Programming Language and Systems Research Group
School of Computer Science and Engineering
University of New South Wales
http://www.cse.unsw.edu.au/~seanl
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Colin Paul Adams
>>>>> "Sean" == Sean Lee <[hidden email]> writes:

    >> The following code probably would do what I wanted to do.
    Sean> I mean "what you wanted to do." :)

I guessed, but then, when it didn't, I decided you typed the right
thing in the first place :-)
--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Sean Lee-4
In reply to this post by Colin Paul Adams
You get some random values? or no change at all on the state?

On Wed, Mar 18, 2009 at 9:45 PM, Colin Paul Adams
<[hidden email]> wrote:

>>>>>> "Sean" == Sean Lee <[hidden email]> writes:
>
> ? ?Sean> Hi Colin The following code probably would do what I wanted
> ? ?Sean> to do.
>
> ? ?Sean> play_move :: IORef Game_state -> IO () play_move
> ? ?Sean> game_state_ior = do (_, state, _) <- readIORef
> ? ?Sean> game_state_ior putStr "Playing AI: " start_time <-
> ? ?Sean> getCurrentTime let move = recommended_move state end_time <-
> ? ?Sean> move `seq` (modifyIORef game_state_ior $!
> ? ?Sean> update_interactive_from_move move) `seq` getCurrentTime
> ? ?Sean> putStrLn $ show $ (diffUTCTime end_time start_time)
>
> ? ?Sean> Due to the non-strictness of Haskell, the evaluation of the
> ? ?Sean> expressions between start_time and end_time is deferred
> ? ?Sean> until there is a need. ?By using `seq` and ($!), the
> ? ?Sean> strictness can be forced.
>
> It certainly causes a time delay, and a non-zero time is printed, but
> the state doesn't get modified correctly now.
>
> ??
>
> I will ponder Daniel's suggestion.
> --
> Colin Adams
> Preston Lancashire
>



--
Sean Lee
PhD Student
Programming Language and Systems Research Group
School of Computer Science and Engineering
University of New South Wales
http://www.cse.unsw.edu.au/~seanl
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Colin Paul Adams
>>>>> "Sean" == Sean Lee <[hidden email]> writes:

    Sean> You get some random values? or no change at all on the
    Sean> state?

I'm not sure if the state has changed at all or not. Certainly it has
not changed correctly - the move does not get made.

As for Daniel's suggestion, I can't compile it because it says I need
an instance of NFData for Move.Move. I'm not sure what that involves.

Anyway, I don't think that evaluating move is necessarily the
solution. I need to force the entire evaluation of modifyIORef.
--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Daniel Fischer-4
In reply to this post by Sean Lee-4
Am Mittwoch, 18. M?rz 2009 11:54 schrieb Sean Lee:

> You get some random values? or no change at all on the state?
>
> On Wed, Mar 18, 2009 at 9:45 PM, Colin Paul Adams
>
> <[hidden email]> wrote:
> >>>>>> "Sean" == Sean Lee <[hidden email]> writes:
> >
> >    Sean> Hi Colin The following code probably would do what I wanted
> >    Sean> to do.
> >
> >    Sean> play_move :: IORef Game_state -> IO () play_move
> >    Sean> game_state_ior = do (_, state, _) <- readIORef
> >    Sean> game_state_ior putStr "Playing AI: " start_time <-
> >    Sean> getCurrentTime let move = recommended_move state end_time <-
> >    Sean> move `seq` (modifyIORef game_state_ior $!
> >    Sean> update_interactive_from_move move) `seq` getCurrentTime

that should probably have been

move `seq` (modifyIORef game_state_ior $! ... ) >> getCurrentTime

value `seq` ioAction1 `seq` ioAction2

doesn't execute ioAction1.

> >    Sean> putStrLn $ show $ (diffUTCTime end_time start_time)
> >
> >    Sean> Due to the non-strictness of Haskell, the evaluation of the
> >    Sean> expressions between start_time and end_time is deferred
> >    Sean> until there is a need.  By using `seq` and ($!), the
> >    Sean> strictness can be forced.
> >
> > It certainly causes a time delay, and a non-zero time is printed, but
> > the state doesn't get modified correctly now.
> >
> > ??
> >
> > I will ponder Daniel's suggestion.
> > --
> > Colin Adams
> > Preston Lancashire

Reply | Threaded
Open this post in threaded view
|

How to display a time difference?

Colin Paul Adams
>>>>> "Daniel" == Daniel Fischer <[hidden email]> writes:

    Daniel> that should probably have been

    Daniel> move `seq` (modifyIORef game_state_ior $! ... ) >>
    Daniel> getCurrentTime

    Daniel> value `seq` ioAction1 `seq` ioAction2

    Daniel> doesn't execute ioAction1.

That did the trick!

Thanks everyone.
--
Colin Adams
Preston Lancashire