module Data.SBV.Utils.TDiff
( timeIf
, Timing(..)
, TimedStep(..)
, TimingInfo
, showTDiff
)
where
import Control.DeepSeq (rnf, NFData(..))
import System.Time (TimeDiff(..), normalizeTimeDiff, diffClockTimes, getClockTime)
import Numeric (showFFloat)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.IORef(IORef, modifyIORef')
data Timing = NoTiming | PrintTiming | SaveTiming (IORef TimingInfo)
data TimedStep = ProblemConstruction | Translation | WorkByProver String
deriving (Eq, Ord, Show)
type TimingInfo = Map TimedStep TimeDiff
timedStepLabel :: TimedStep -> String
timedStepLabel lbl =
case lbl of
ProblemConstruction -> "problem construction"
Translation -> "translation"
WorkByProver x -> x
showTDiff :: TimeDiff -> String
showTDiff itd = et
where td = normalizeTimeDiff itd
vals = dropWhile (\(v, _) -> v == 0) (zip [tdYear td, tdMonth td, tdDay td, tdHour td, tdMin td] "YMDhm")
sec = ' ' : show (tdSec td) ++ dropWhile (/= '.') pico
pico = showFFloat (Just 3) (((10**(-12))::Double) * fromIntegral (tdPicosec td)) "s"
et = concatMap (\(v, c) -> ' ':show v ++ [c]) vals ++ sec
timeIf :: NFData a => Timing -> TimedStep -> IO a -> IO a
timeIf how what m =
case how of
NoTiming -> m
PrintTiming ->
do (elapsed,a) <- doTime m
putStrLn $ "** Elapsed " ++ timedStepLabel what ++ " time:" ++ showTDiff elapsed
return a
SaveTiming here ->
do (elapsed,a) <- doTime m
modifyIORef' here (Map.insert what elapsed)
return a
doTime :: NFData a => IO a -> IO (TimeDiff,a)
doTime m = do start <- getClockTime
r <- m
end <- rnf r `seq` getClockTime
let elapsed = diffClockTimes end start
elapsed `seq` return (elapsed, r)