Move time formatting routines in the Time module

This commit is contained in:
Harendra Kumar 2019-01-12 02:15:28 +05:30
parent 06a827f826
commit 34edd618b0
2 changed files with 72 additions and 36 deletions

View File

@ -134,9 +134,8 @@ import GHC.IO (IO(..))
import Streamly.Time.Clock (Clock(..), getTime)
import Streamly.Time.Units
(AbsTime, NanoSecond64(..), MicroSecond64(..), diffAbsTime64,
fromRelTime64, toRelTime64)
fromRelTime64, toRelTime64, showNanoSecond64, showRelTime64)
import System.IO (hPutStrLn, stderr)
import Text.Printf (printf)
import qualified Data.Heap as H
import qualified Data.Set as S
@ -643,31 +642,6 @@ collectLatency sv yinfo drain = do
-- Dumping the SVar for debug/diag
-------------------------------------------------------------------------------
-- | Convert a number of seconds to a string. The string will consist
-- of four decimal places, followed by a short description of the time
-- units.
secs :: Double -> String
secs k
| k < 0 = '-' : secs (-k)
| k >= 1 = k `with` "s"
| k >= 1e-3 = (k*1e3) `with` "ms"
#ifdef mingw32_HOST_OS
| k >= 1e-6 = (k*1e6) `with` "us"
#else
| k >= 1e-6 = (k*1e6) `with` "μs"
#endif
| k >= 1e-9 = (k*1e9) `with` "ns"
| k >= 1e-12 = (k*1e12) `with` "ps"
| k >= 1e-15 = (k*1e15) `with` "fs"
| k >= 1e-18 = (k*1e18) `with` "as"
| otherwise = printf "%g s" k
where with (t :: Double) (u :: String)
| t >= 1e9 = printf "%.4g %s" t u
| t >= 1e3 = printf "%.0f %s" t u
| t >= 1e2 = printf "%.1f %s" t u
| t >= 1e1 = printf "%.2f %s" t u
| otherwise = printf "%.3f %s" t u
dumpSVarStats :: SVar t m a -> SVarStats -> SVarStyle -> IO String
dumpSVarStats sv ss style = do
case yieldRateInfo sv of
@ -709,21 +683,17 @@ dumpSVarStats sv ss style = do
then "\nheap max size = " <> show maxHp
else "")
<> (if minLat > 0
then "\nmin worker latency = "
<> secs (fromIntegral minLat * 1e-9)
then "\nmin worker latency = " <> showNanoSecond64 minLat
else "")
<> (if maxLat > 0
then "\nmax worker latency = "
<> secs (fromIntegral maxLat * 1e-9)
then "\nmax worker latency = " <> showNanoSecond64 maxLat
else "")
<> (if avgCnt > 0
then let lat = avgTime `div` fromIntegral avgCnt
in "\navg worker latency = "
<> secs (fromIntegral lat * 1e-9)
in "\navg worker latency = " <> showNanoSecond64 lat
else "")
<> (if svarLat > 0
then "\nSVar latency = "
<> secs (fromIntegral svarLat * 1e-9)
then "\nSVar latency = " <> showRelTime64 svarLat
else "")
<> (if svarCnt > 0
then "\nSVar yield count = " <> show svarCnt

View File

@ -1,5 +1,6 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
#include "inline.hs"
@ -24,6 +25,7 @@ module Streamly.Time.Units
, NanoSecond64(..)
, MicroSecond64(..)
, MilliSecond64(..)
, showNanoSecond64
-- * Absolute times (using TimeSpec)
, AbsTime(..)
@ -43,10 +45,12 @@ module Streamly.Time.Units
, fromRelTime64
, diffAbsTime64
, addToAbsTime64
, showRelTime64
)
where
import Data.Int
import Text.Printf (printf)
-------------------------------------------------------------------------------
-- Some constants
@ -68,11 +72,25 @@ tenPower9 = 1000000000
-- Time Unit Representations
-------------------------------------------------------------------------------
-- XXX We should be able to use type families to use different represenations
-- for a unit.
--
-- Second Rational
-- Second Double
-- Second Int64
-- Second Integer
-- NanoSecond Int64
-- ...
-- Double or Fixed would be a much better representation so that we do not lose
-- information between conversions. However, for faster arithmetic operations
-- we use an 'Int64' here. When we need convservation of values we can use a
-- different system of units with a Fixed precision.
--
-------------------------------------------------------------------------------
-- Integral Units
-------------------------------------------------------------------------------
-- | An 'Int64' time representation with a nanosecond resolution. It can
-- represent time up to ~292 years.
newtype NanoSecond64 = NanoSecond64 Int64
@ -115,6 +133,10 @@ newtype MilliSecond64 = MilliSecond64 Int64
, Ord
)
-------------------------------------------------------------------------------
-- Fractional Units
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- TimeSpec representation
-------------------------------------------------------------------------------
@ -403,3 +425,47 @@ diffAbsTime (AbsTime t1) (AbsTime t2) = RelTime (t1 - t2)
{-# INLINE addToAbsTime #-}
addToAbsTime :: AbsTime -> RelTime -> AbsTime
addToAbsTime (AbsTime t1) (RelTime t2) = AbsTime $ t1 + t2
-------------------------------------------------------------------------------
-- Formatting and printing
-------------------------------------------------------------------------------
-- | Convert nanoseconds to a string showing time in an appropriate unit.
showNanoSecond64 :: NanoSecond64 -> String
showNanoSecond64 time@(NanoSecond64 ns)
| time < 0 = '-' : showNanoSecond64 (-time)
| ns < 1000 = fromIntegral ns `with` "ns"
#ifdef mingw32_HOST_OS
| ns < 1000000 = (fromIntegral ns / 1000) `with` "us"
#else
| ns < 1000000 = (fromIntegral ns / 1000) `with` "μs"
#endif
| ns < 1000000000 = (fromIntegral ns / 1000000) `with` "ms"
| ns < (60 * 1000000000) = (fromIntegral ns / 1000000000) `with` "s"
| ns < (60 * 60 * 1000000000) =
(fromIntegral ns / (60 * 1000000000)) `with` "min"
| ns < (24 * 60 * 60 * 1000000000) =
(fromIntegral ns / (60 * 60 * 1000000000)) `with` "hr"
| ns < (365 * 24 * 60 * 60 * 1000000000) =
(fromIntegral ns / (24 * 60 * 60 * 1000000000)) `with` "days"
| otherwise =
(fromIntegral ns / (365 * 24 * 60 * 60 * 1000000000)) `with` "years"
where with (t :: Double) (u :: String)
| t >= 1e9 = printf "%.4g %s" t u
| t >= 1e3 = printf "%.0f %s" t u
| t >= 1e2 = printf "%.1f %s" t u
| t >= 1e1 = printf "%.2f %s" t u
| otherwise = printf "%.3f %s" t u
-- In general we should be able to show the time in a specified unit, if we
-- omit the unit we can show it in an automatically chosen one.
{-
data UnitName =
Nano
| Micro
| Milli
| Sec
-}
showRelTime64 :: RelTime64 -> String
showRelTime64 = showNanoSecond64 . fromRelTime64