{-# LANGUAGE OverloadedStrings #-}

-- | Unification of the various different performance measure types, mostly to unify reporting and data management.
module Perf.Measure
  ( MeasureType (..),
    parseMeasure,
    measureDs,
    measureLabels,
  )
where

import Data.Text (Text)
import Options.Applicative
import Perf.Space
import Perf.Time
import Perf.Types
import Prelude hiding (cycle)

-- | Command-line measurement options.
data MeasureType = MeasureTime | MeasureSpace | MeasureSpaceTime | MeasureAllocation deriving (MeasureType -> MeasureType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MeasureType -> MeasureType -> Bool
$c/= :: MeasureType -> MeasureType -> Bool
== :: MeasureType -> MeasureType -> Bool
$c== :: MeasureType -> MeasureType -> Bool
Eq, Int -> MeasureType -> ShowS
[MeasureType] -> ShowS
MeasureType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MeasureType] -> ShowS
$cshowList :: [MeasureType] -> ShowS
show :: MeasureType -> String
$cshow :: MeasureType -> String
showsPrec :: Int -> MeasureType -> ShowS
$cshowsPrec :: Int -> MeasureType -> ShowS
Show)

-- | Parse command-line 'MeasureType' options.
parseMeasure :: Parser MeasureType
parseMeasure :: Parser MeasureType
parseMeasure =
  forall a. a -> Mod FlagFields a -> Parser a
flag' MeasureType
MeasureTime (forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"time" forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. String -> Mod f a
help String
"measure time performance")
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. a -> Mod FlagFields a -> Parser a
flag' MeasureType
MeasureSpace (forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"space" forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. String -> Mod f a
help String
"measure space performance")
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. a -> Mod FlagFields a -> Parser a
flag' MeasureType
MeasureSpaceTime (forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"spacetime" forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. String -> Mod f a
help String
"measure both space and time performance")
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. a -> Mod FlagFields a -> Parser a
flag' MeasureType
MeasureAllocation (forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"allocation" forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> *) a. String -> Mod f a
help String
"measure bytes allocated")
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (f :: * -> *) a. Applicative f => a -> f a
pure MeasureType
MeasureTime

-- | unification of the different measurements to being a list of doubles.
measureDs :: MeasureType -> Int -> Measure IO [[Double]]
measureDs :: MeasureType -> Int -> Measure IO [[Double]]
measureDs MeasureType
mt Int
n =
  case MeasureType
mt of
    MeasureType
MeasureTime -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. a -> [a] -> [a]
: []) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Measure IO [Cycles]
times Int
n
    MeasureType
MeasureSpace -> forall (m :: * -> *) t.
Monad m =>
Int -> StepMeasure m t -> Measure m [t]
toMeasureN Int
n (forall a. Num a => SpaceStats -> [a]
ssToList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> StepMeasure IO SpaceStats
space Bool
False)
    MeasureType
MeasureSpaceTime -> forall (m :: * -> *) t.
Monad m =>
Int -> StepMeasure m t -> Measure m [t]
toMeasureN Int
n ((\SpaceStats
x Cycles
y -> forall a. Num a => SpaceStats -> [a]
ssToList SpaceStats
x forall a. Semigroup a => a -> a -> a
<> [forall a b. (Integral a, Num b) => a -> b
fromIntegral Cycles
y]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> StepMeasure IO SpaceStats
space Bool
False forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StepMeasure IO Cycles
stepTime)
    MeasureType
MeasureAllocation -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. a -> [a] -> [a]
: []) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) t.
Monad m =>
Int -> StepMeasure m t -> Measure m [t]
toMeasureN Int
n (Bool -> StepMeasure IO Bytes
allocation Bool
False)

-- | unification of the different measurements to being a list of doubles.
measureLabels :: MeasureType -> [Text]
measureLabels :: MeasureType -> [Text]
measureLabels MeasureType
mt =
  case MeasureType
mt of
    MeasureType
MeasureTime -> [Text
"time"]
    MeasureType
MeasureSpace -> [Text]
spaceLabels
    MeasureType
MeasureSpaceTime -> [Text]
spaceLabels forall a. Semigroup a => a -> a -> a
<> [Text
"time"]
    MeasureType
MeasureAllocation -> [Text
"allocation"]