module Agda.Utils.Benchmark where
import Prelude hiding (null)
import Control.DeepSeq
import qualified Control.Exception as E (evaluate)
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State
import Control.Monad.IO.Class ( MonadIO(..) )
import Data.Function (on)
import qualified Data.List as List
import Data.Monoid
import Data.Maybe
import GHC.Generics (Generic)
import qualified Text.PrettyPrint.Boxes as Boxes
import Agda.Utils.ListT
import Agda.Utils.Null
import Agda.Utils.Monad hiding (finally)
import qualified Agda.Utils.Maybe.Strict as Strict
import Agda.Syntax.Common.Pretty
import Agda.Utils.Time
import Agda.Utils.Trie (Trie)
import qualified Agda.Utils.Trie as Trie
type Account a = [a]
type CurrentAccount a = Strict.Maybe (Account a, CPUTime)
type Timings a = Trie a CPUTime
data BenchmarkOn a = BenchmarkOff | BenchmarkOn | BenchmarkSome (Account a -> Bool)
deriving (forall x. BenchmarkOn a -> Rep (BenchmarkOn a) x)
-> (forall x. Rep (BenchmarkOn a) x -> BenchmarkOn a)
-> Generic (BenchmarkOn a)
forall x. Rep (BenchmarkOn a) x -> BenchmarkOn a
forall x. BenchmarkOn a -> Rep (BenchmarkOn a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (BenchmarkOn a) x -> BenchmarkOn a
forall a x. BenchmarkOn a -> Rep (BenchmarkOn a) x
$cfrom :: forall a x. BenchmarkOn a -> Rep (BenchmarkOn a) x
from :: forall x. BenchmarkOn a -> Rep (BenchmarkOn a) x
$cto :: forall a x. Rep (BenchmarkOn a) x -> BenchmarkOn a
to :: forall x. Rep (BenchmarkOn a) x -> BenchmarkOn a
Generic
isBenchmarkOn :: Account a -> BenchmarkOn a -> Bool
isBenchmarkOn :: forall a. Account a -> BenchmarkOn a -> Bool
isBenchmarkOn Account a
_ BenchmarkOn a
BenchmarkOff = Bool
False
isBenchmarkOn Account a
_ BenchmarkOn a
BenchmarkOn = Bool
True
isBenchmarkOn Account a
a (BenchmarkSome Account a -> Bool
p) = Account a -> Bool
p Account a
a
data Benchmark a = Benchmark
{ forall a. Benchmark a -> BenchmarkOn a
benchmarkOn :: !(BenchmarkOn a)
, forall a. Benchmark a -> CurrentAccount a
currentAccount :: !(CurrentAccount a)
, forall a. Benchmark a -> Timings a
timings :: !(Timings a)
}
deriving (forall x. Benchmark a -> Rep (Benchmark a) x)
-> (forall x. Rep (Benchmark a) x -> Benchmark a)
-> Generic (Benchmark a)
forall x. Rep (Benchmark a) x -> Benchmark a
forall x. Benchmark a -> Rep (Benchmark a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Benchmark a) x -> Benchmark a
forall a x. Benchmark a -> Rep (Benchmark a) x
$cfrom :: forall a x. Benchmark a -> Rep (Benchmark a) x
from :: forall x. Benchmark a -> Rep (Benchmark a) x
$cto :: forall a x. Rep (Benchmark a) x -> Benchmark a
to :: forall x. Rep (Benchmark a) x -> Benchmark a
Generic
instance Null (Benchmark a) where
empty :: Benchmark a
empty = Benchmark
{ benchmarkOn :: BenchmarkOn a
benchmarkOn = BenchmarkOn a
forall a. BenchmarkOn a
BenchmarkOff
, currentAccount :: CurrentAccount a
currentAccount = CurrentAccount a
forall a. Maybe a
Strict.Nothing
, timings :: Timings a
timings = Timings a
forall a. Null a => a
empty
}
null :: Benchmark a -> Bool
null = Timings a -> Bool
forall a. Null a => a -> Bool
null (Timings a -> Bool)
-> (Benchmark a -> Timings a) -> Benchmark a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Benchmark a -> Timings a
forall a. Benchmark a -> Timings a
timings
mapBenchmarkOn :: (BenchmarkOn a -> BenchmarkOn a) -> Benchmark a -> Benchmark a
mapBenchmarkOn :: forall a.
(BenchmarkOn a -> BenchmarkOn a) -> Benchmark a -> Benchmark a
mapBenchmarkOn BenchmarkOn a -> BenchmarkOn a
f Benchmark a
b = Benchmark a
b { benchmarkOn = f $ benchmarkOn b }
mapCurrentAccount ::
(CurrentAccount a -> CurrentAccount a) -> Benchmark a -> Benchmark a
mapCurrentAccount :: forall a.
(CurrentAccount a -> CurrentAccount a)
-> Benchmark a -> Benchmark a
mapCurrentAccount CurrentAccount a -> CurrentAccount a
f Benchmark a
b = Benchmark a
b { currentAccount = f (currentAccount b) }
mapTimings :: (Timings a -> Timings a) -> Benchmark a -> Benchmark a
mapTimings :: forall a. (Timings a -> Timings a) -> Benchmark a -> Benchmark a
mapTimings Timings a -> Timings a
f Benchmark a
b = Benchmark a
b { timings = f (timings b) }
addCPUTime :: Ord a => Account a -> CPUTime -> Benchmark a -> Benchmark a
addCPUTime :: forall a.
Ord a =>
Account a -> CPUTime -> Benchmark a -> Benchmark a
addCPUTime Account a
acc CPUTime
t = (Timings a -> Timings a) -> Benchmark a -> Benchmark a
forall a. (Timings a -> Timings a) -> Benchmark a -> Benchmark a
mapTimings ((CPUTime -> CPUTime -> CPUTime)
-> Account a -> CPUTime -> Timings a -> Timings a
forall k v.
Ord k =>
(v -> v -> v) -> [k] -> v -> Trie k v -> Trie k v
Trie.insertWith CPUTime -> CPUTime -> CPUTime
forall a. Num a => a -> a -> a
(+) Account a
acc CPUTime
t)
instance (Ord a, Pretty a) => Pretty (Benchmark a) where
pretty :: Benchmark a -> Doc
pretty Benchmark a
b = [Char] -> Doc
forall a. [Char] -> Doc a
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ Box -> [Char]
Boxes.render Box
table
where
trie :: Timings a
trie = Benchmark a -> Timings a
forall a. Benchmark a -> Timings a
timings Benchmark a
b
([[a]]
accounts, [(CPUTime, CPUTime)]
times0) = [([a], (CPUTime, CPUTime))] -> ([[a]], [(CPUTime, CPUTime)])
forall a b. [(a, b)] -> ([a], [b])
unzip ([([a], (CPUTime, CPUTime))] -> ([[a]], [(CPUTime, CPUTime)]))
-> [([a], (CPUTime, CPUTime))] -> ([[a]], [(CPUTime, CPUTime)])
forall a b. (a -> b) -> a -> b
$ ((CPUTime, CPUTime) -> (CPUTime, CPUTime) -> Ordering)
-> Trie a (CPUTime, CPUTime) -> [([a], (CPUTime, CPUTime))]
forall k v. Ord k => (v -> v -> Ordering) -> Trie k v -> [([k], v)]
Trie.toListOrderedBy ((CPUTime -> CPUTime -> Ordering) -> CPUTime -> CPUTime -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip CPUTime -> CPUTime -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (CPUTime -> CPUTime -> Ordering)
-> ((CPUTime, CPUTime) -> CPUTime)
-> (CPUTime, CPUTime)
-> (CPUTime, CPUTime)
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (CPUTime, CPUTime) -> CPUTime
forall a b. (a, b) -> b
snd)
(Trie a (CPUTime, CPUTime) -> [([a], (CPUTime, CPUTime))])
-> Trie a (CPUTime, CPUTime) -> [([a], (CPUTime, CPUTime))]
forall a b. (a -> b) -> a -> b
$ ((CPUTime, CPUTime) -> Bool)
-> Trie a (CPUTime, CPUTime) -> Trie a (CPUTime, CPUTime)
forall k v. Ord k => (v -> Bool) -> Trie k v -> Trie k v
Trie.filter ((CPUTime -> CPUTime -> Bool
forall a. Ord a => a -> a -> Bool
> Integer -> CPUTime
fromMilliseconds Integer
10) (CPUTime -> Bool)
-> ((CPUTime, CPUTime) -> CPUTime) -> (CPUTime, CPUTime) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CPUTime, CPUTime) -> CPUTime
forall a b. (a, b) -> b
snd)
(Trie a (CPUTime, CPUTime) -> Trie a (CPUTime, CPUTime))
-> Trie a (CPUTime, CPUTime) -> Trie a (CPUTime, CPUTime)
forall a b. (a -> b) -> a -> b
$ (Timings a -> Maybe (CPUTime, CPUTime))
-> Timings a -> Trie a (CPUTime, CPUTime)
forall k u v.
Ord k =>
(Trie k u -> Maybe v) -> Trie k u -> Trie k v
Trie.mapSubTries ((CPUTime, CPUTime) -> Maybe (CPUTime, CPUTime)
forall a. a -> Maybe a
Just ((CPUTime, CPUTime) -> Maybe (CPUTime, CPUTime))
-> (Timings a -> (CPUTime, CPUTime))
-> Timings a
-> Maybe (CPUTime, CPUTime)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Timings a -> (CPUTime, CPUTime)
forall {b} {k}. (Num b, Ord k) => Trie k b -> (b, b)
aggr) Timings a
trie
times :: [CPUTime]
times = ((CPUTime, CPUTime) -> CPUTime)
-> [(CPUTime, CPUTime)] -> [CPUTime]
forall a b. (a -> b) -> [a] -> [b]
map (CPUTime, CPUTime) -> CPUTime
forall a b. (a, b) -> a
fst [(CPUTime, CPUTime)]
times0
aggr :: Trie k b -> (b, b)
aggr Trie k b
t = (b -> Maybe b -> b
forall a. a -> Maybe a -> a
fromMaybe b
0 (Maybe b -> b) -> Maybe b -> b
forall a b. (a -> b) -> a -> b
$ [k] -> Trie k b -> Maybe b
forall k v. Ord k => [k] -> Trie k v -> Maybe v
Trie.lookup [] Trie k b
t, Sum b -> b
forall a. Sum a -> a
getSum (Sum b -> b) -> Sum b -> b
forall a b. (a -> b) -> a -> b
$ (b -> Sum b) -> Trie k b -> Sum b
forall m a. Monoid m => (a -> m) -> Trie k a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap b -> Sum b
forall a. a -> Sum a
Sum Trie k b
t)
aggrTimes :: [Box]
aggrTimes = do
(a, (t, aggrT)) <- [[a]] -> [(CPUTime, CPUTime)] -> [([a], (CPUTime, CPUTime))]
forall a b. [a] -> [b] -> [(a, b)]
zip [[a]]
accounts [(CPUTime, CPUTime)]
times0
return $ if t == aggrT || null a
then ""
else Boxes.text $ "(" ++ prettyShow aggrT ++ ")"
table :: Box
table = Int -> Alignment -> [Box] -> Box
forall (f :: * -> *).
Foldable f =>
Int -> Alignment -> f Box -> Box
Boxes.hsep Int
1 Alignment
Boxes.left [Box
col1, Box
col2, Box
col3]
col1 :: Box
col1 = Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
Boxes.vcat Alignment
Boxes.left ([Box] -> Box) -> [Box] -> Box
forall a b. (a -> b) -> a -> b
$
([Char] -> Box) -> [[Char]] -> [Box]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Box
Boxes.text ([[Char]] -> [Box]) -> [[Char]] -> [Box]
forall a b. (a -> b) -> a -> b
$
[Char]
"Total" [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: ([a] -> [Char]) -> [[a]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> [Char]
forall {a}. Pretty a => [a] -> [Char]
showAccount [[a]]
accounts
col2 :: Box
col2 = Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
Boxes.vcat Alignment
Boxes.right ([Box] -> Box) -> [Box] -> Box
forall a b. (a -> b) -> a -> b
$
(CPUTime -> Box) -> [CPUTime] -> [Box]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> Box
Boxes.text ([Char] -> Box) -> (CPUTime -> [Char]) -> CPUTime -> Box
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CPUTime -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow) ([CPUTime] -> [Box]) -> [CPUTime] -> [Box]
forall a b. (a -> b) -> a -> b
$
[CPUTime] -> CPUTime
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [CPUTime]
times CPUTime -> [CPUTime] -> [CPUTime]
forall a. a -> [a] -> [a]
: [CPUTime]
times
col3 :: Box
col3 = Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
Boxes.vcat Alignment
Boxes.right ([Box] -> Box) -> [Box] -> Box
forall a b. (a -> b) -> a -> b
$
Box
"" Box -> [Box] -> [Box]
forall a. a -> [a] -> [a]
: [Box]
aggrTimes
showAccount :: [a] -> [Char]
showAccount [] = [Char]
"Miscellaneous"
showAccount [a]
ks = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
List.intercalate [Char]
"." ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ (a -> [Char]) -> [a] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map a -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow [a]
ks
class (Ord (BenchPhase m), Functor m, MonadIO m) => MonadBench m where
type BenchPhase m
getBenchmark :: m (Benchmark (BenchPhase m))
putBenchmark :: Benchmark (BenchPhase m) -> m ()
putBenchmark Benchmark (BenchPhase m)
b = (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall a b. (a -> b) -> a -> b
$ Benchmark (BenchPhase m)
-> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
forall a b. a -> b -> a
const Benchmark (BenchPhase m)
b
modifyBenchmark :: (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
f = do
b <- m (Benchmark (BenchPhase m))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
putBenchmark $! f b
finally :: m b -> m c -> m b
getsBenchmark :: MonadBench m => (Benchmark (BenchPhase m) -> c) -> m c
getsBenchmark :: forall (m :: * -> *) c.
MonadBench m =>
(Benchmark (BenchPhase m) -> c) -> m c
getsBenchmark Benchmark (BenchPhase m) -> c
f = Benchmark (BenchPhase m) -> c
f (Benchmark (BenchPhase m) -> c)
-> m (Benchmark (BenchPhase m)) -> m c
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Benchmark (BenchPhase m))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
instance MonadBench m => MonadBench (ReaderT r m) where
type BenchPhase (ReaderT r m) = BenchPhase m
getBenchmark :: ReaderT r m (Benchmark (BenchPhase (ReaderT r m)))
getBenchmark = m (Benchmark (BenchPhase (ReaderT r m)))
-> ReaderT r m (Benchmark (BenchPhase (ReaderT r m)))
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Benchmark (BenchPhase (ReaderT r m)))
-> ReaderT r m (Benchmark (BenchPhase (ReaderT r m))))
-> m (Benchmark (BenchPhase (ReaderT r m)))
-> ReaderT r m (Benchmark (BenchPhase (ReaderT r m)))
forall a b. (a -> b) -> a -> b
$ m (Benchmark (BenchPhase m))
m (Benchmark (BenchPhase (ReaderT r m)))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
putBenchmark :: Benchmark (BenchPhase (ReaderT r m)) -> ReaderT r m ()
putBenchmark = m () -> ReaderT r m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (Benchmark (BenchPhase m) -> m ())
-> Benchmark (BenchPhase m)
-> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Benchmark (BenchPhase m) -> m ()
forall (m :: * -> *).
MonadBench m =>
Benchmark (BenchPhase m) -> m ()
putBenchmark
modifyBenchmark :: (Benchmark (BenchPhase (ReaderT r m))
-> Benchmark (BenchPhase (ReaderT r m)))
-> ReaderT r m ()
modifyBenchmark = m () -> ReaderT r m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark
finally :: forall b c. ReaderT r m b -> ReaderT r m c -> ReaderT r m b
finally ReaderT r m b
m ReaderT r m c
f = (r -> m b) -> ReaderT r m b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m b) -> ReaderT r m b) -> (r -> m b) -> ReaderT r m b
forall a b. (a -> b) -> a -> b
$ \ r
r ->
m b -> m c -> m b
forall b c. m b -> m c -> m b
forall (m :: * -> *) b c. MonadBench m => m b -> m c -> m b
finally (ReaderT r m b
m ReaderT r m b -> r -> m b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`runReaderT` r
r) (ReaderT r m c
f ReaderT r m c -> r -> m c
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`runReaderT` r
r)
instance (MonadBench m, Monoid w) => MonadBench (WriterT w m) where
type BenchPhase (WriterT w m) = BenchPhase m
getBenchmark :: WriterT w m (Benchmark (BenchPhase (WriterT w m)))
getBenchmark = m (Benchmark (BenchPhase (WriterT w m)))
-> WriterT w m (Benchmark (BenchPhase (WriterT w m)))
forall (m :: * -> *) a. Monad m => m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Benchmark (BenchPhase (WriterT w m)))
-> WriterT w m (Benchmark (BenchPhase (WriterT w m))))
-> m (Benchmark (BenchPhase (WriterT w m)))
-> WriterT w m (Benchmark (BenchPhase (WriterT w m)))
forall a b. (a -> b) -> a -> b
$ m (Benchmark (BenchPhase m))
m (Benchmark (BenchPhase (WriterT w m)))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
putBenchmark :: Benchmark (BenchPhase (WriterT w m)) -> WriterT w m ()
putBenchmark = m () -> WriterT w m ()
forall (m :: * -> *) a. Monad m => m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (Benchmark (BenchPhase m) -> m ())
-> Benchmark (BenchPhase m)
-> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Benchmark (BenchPhase m) -> m ()
forall (m :: * -> *).
MonadBench m =>
Benchmark (BenchPhase m) -> m ()
putBenchmark
modifyBenchmark :: (Benchmark (BenchPhase (WriterT w m))
-> Benchmark (BenchPhase (WriterT w m)))
-> WriterT w m ()
modifyBenchmark = m () -> WriterT w m ()
forall (m :: * -> *) a. Monad m => m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark
finally :: forall b c. WriterT w m b -> WriterT w m c -> WriterT w m b
finally WriterT w m b
m WriterT w m c
f = m (b, w) -> WriterT w m b
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT (m (b, w) -> WriterT w m b) -> m (b, w) -> WriterT w m b
forall a b. (a -> b) -> a -> b
$ m (b, w) -> m (c, w) -> m (b, w)
forall b c. m b -> m c -> m b
forall (m :: * -> *) b c. MonadBench m => m b -> m c -> m b
finally (WriterT w m b -> m (b, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT WriterT w m b
m) (WriterT w m c -> m (c, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT WriterT w m c
f)
instance MonadBench m => MonadBench (StateT r m) where
type BenchPhase (StateT r m) = BenchPhase m
getBenchmark :: StateT r m (Benchmark (BenchPhase (StateT r m)))
getBenchmark = m (Benchmark (BenchPhase (StateT r m)))
-> StateT r m (Benchmark (BenchPhase (StateT r m)))
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Benchmark (BenchPhase (StateT r m)))
-> StateT r m (Benchmark (BenchPhase (StateT r m))))
-> m (Benchmark (BenchPhase (StateT r m)))
-> StateT r m (Benchmark (BenchPhase (StateT r m)))
forall a b. (a -> b) -> a -> b
$ m (Benchmark (BenchPhase m))
m (Benchmark (BenchPhase (StateT r m)))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
putBenchmark :: Benchmark (BenchPhase (StateT r m)) -> StateT r m ()
putBenchmark = m () -> StateT r m ()
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT r m ())
-> (Benchmark (BenchPhase m) -> m ())
-> Benchmark (BenchPhase m)
-> StateT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Benchmark (BenchPhase m) -> m ()
forall (m :: * -> *).
MonadBench m =>
Benchmark (BenchPhase m) -> m ()
putBenchmark
modifyBenchmark :: (Benchmark (BenchPhase (StateT r m))
-> Benchmark (BenchPhase (StateT r m)))
-> StateT r m ()
modifyBenchmark = m () -> StateT r m ()
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT r m ())
-> ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> StateT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark
finally :: forall b c. StateT r m b -> StateT r m c -> StateT r m b
finally StateT r m b
m StateT r m c
f = (r -> m (b, r)) -> StateT r m b
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((r -> m (b, r)) -> StateT r m b)
-> (r -> m (b, r)) -> StateT r m b
forall a b. (a -> b) -> a -> b
$ \r
s ->
m (b, r) -> m (c, r) -> m (b, r)
forall b c. m b -> m c -> m b
forall (m :: * -> *) b c. MonadBench m => m b -> m c -> m b
finally (StateT r m b
m StateT r m b -> r -> m (b, r)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
`runStateT` r
s) (StateT r m c
f StateT r m c -> r -> m (c, r)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
`runStateT` r
s)
instance MonadBench m => MonadBench (ExceptT e m) where
type BenchPhase (ExceptT e m) = BenchPhase m
getBenchmark :: ExceptT e m (Benchmark (BenchPhase (ExceptT e m)))
getBenchmark = m (Benchmark (BenchPhase (ExceptT e m)))
-> ExceptT e m (Benchmark (BenchPhase (ExceptT e m)))
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Benchmark (BenchPhase (ExceptT e m)))
-> ExceptT e m (Benchmark (BenchPhase (ExceptT e m))))
-> m (Benchmark (BenchPhase (ExceptT e m)))
-> ExceptT e m (Benchmark (BenchPhase (ExceptT e m)))
forall a b. (a -> b) -> a -> b
$ m (Benchmark (BenchPhase m))
m (Benchmark (BenchPhase (ExceptT e m)))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
putBenchmark :: Benchmark (BenchPhase (ExceptT e m)) -> ExceptT e m ()
putBenchmark = m () -> ExceptT e m ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT e m ())
-> (Benchmark (BenchPhase m) -> m ())
-> Benchmark (BenchPhase m)
-> ExceptT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Benchmark (BenchPhase m) -> m ()
forall (m :: * -> *).
MonadBench m =>
Benchmark (BenchPhase m) -> m ()
putBenchmark
modifyBenchmark :: (Benchmark (BenchPhase (ExceptT e m))
-> Benchmark (BenchPhase (ExceptT e m)))
-> ExceptT e m ()
modifyBenchmark = m () -> ExceptT e m ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ExceptT e m ())
-> ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> ExceptT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark
finally :: forall b c. ExceptT e m b -> ExceptT e m c -> ExceptT e m b
finally ExceptT e m b
m ExceptT e m c
f = m (Either e b) -> ExceptT e m b
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e b) -> ExceptT e m b)
-> m (Either e b) -> ExceptT e m b
forall a b. (a -> b) -> a -> b
$ m (Either e b) -> m (Either e c) -> m (Either e b)
forall b c. m b -> m c -> m b
forall (m :: * -> *) b c. MonadBench m => m b -> m c -> m b
finally (ExceptT e m b -> m (Either e b)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT ExceptT e m b
m) (ExceptT e m c -> m (Either e c)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT ExceptT e m c
f)
instance MonadBench m => MonadBench (ListT m) where
type BenchPhase (ListT m) = BenchPhase m
getBenchmark :: ListT m (Benchmark (BenchPhase (ListT m)))
getBenchmark = m (Benchmark (BenchPhase m)) -> ListT m (Benchmark (BenchPhase m))
forall (m :: * -> *) a. Monad m => m a -> ListT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (Benchmark (BenchPhase m))
forall (m :: * -> *). MonadBench m => m (Benchmark (BenchPhase m))
getBenchmark
putBenchmark :: Benchmark (BenchPhase (ListT m)) -> ListT m ()
putBenchmark = m () -> ListT m ()
forall (m :: * -> *) a. Monad m => m a -> ListT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ListT m ())
-> (Benchmark (BenchPhase m) -> m ())
-> Benchmark (BenchPhase m)
-> ListT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Benchmark (BenchPhase m) -> m ()
forall (m :: * -> *).
MonadBench m =>
Benchmark (BenchPhase m) -> m ()
putBenchmark
modifyBenchmark :: (Benchmark (BenchPhase (ListT m))
-> Benchmark (BenchPhase (ListT m)))
-> ListT m ()
modifyBenchmark = m () -> ListT m ()
forall (m :: * -> *) a. Monad m => m a -> ListT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ListT m ())
-> ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> ListT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark
finally :: forall b c. ListT m b -> ListT m c -> ListT m b
finally ListT m b
m ListT m c
f = m (Maybe (b, ListT m b)) -> ListT m b
forall (m :: * -> *) a. m (Maybe (a, ListT m a)) -> ListT m a
ListT (m (Maybe (b, ListT m b)) -> ListT m b)
-> m (Maybe (b, ListT m b)) -> ListT m b
forall a b. (a -> b) -> a -> b
$ m (Maybe (b, ListT m b))
-> m (Maybe (c, ListT m c)) -> m (Maybe (b, ListT m b))
forall b c. m b -> m c -> m b
forall (m :: * -> *) b c. MonadBench m => m b -> m c -> m b
finally (ListT m b -> m (Maybe (b, ListT m b))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
runListT ListT m b
m) (ListT m c -> m (Maybe (c, ListT m c))
forall (m :: * -> *) a. ListT m a -> m (Maybe (a, ListT m a))
runListT ListT m c
f)
setBenchmarking :: MonadBench m => BenchmarkOn (BenchPhase m) -> m ()
setBenchmarking :: forall (m :: * -> *).
MonadBench m =>
BenchmarkOn (BenchPhase m) -> m ()
setBenchmarking BenchmarkOn (BenchPhase m)
b = (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall a b. (a -> b) -> a -> b
$ (BenchmarkOn (BenchPhase m) -> BenchmarkOn (BenchPhase m))
-> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
forall a.
(BenchmarkOn a -> BenchmarkOn a) -> Benchmark a -> Benchmark a
mapBenchmarkOn ((BenchmarkOn (BenchPhase m) -> BenchmarkOn (BenchPhase m))
-> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> (BenchmarkOn (BenchPhase m) -> BenchmarkOn (BenchPhase m))
-> Benchmark (BenchPhase m)
-> Benchmark (BenchPhase m)
forall a b. (a -> b) -> a -> b
$ BenchmarkOn (BenchPhase m)
-> BenchmarkOn (BenchPhase m) -> BenchmarkOn (BenchPhase m)
forall a b. a -> b -> a
const BenchmarkOn (BenchPhase m)
b
switchBenchmarking :: MonadBench m
=> Strict.Maybe (Account (BenchPhase m))
-> m (Strict.Maybe (Account (BenchPhase m)))
switchBenchmarking :: forall (m :: * -> *).
MonadBench m =>
Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
switchBenchmarking Maybe (Account (BenchPhase m))
newAccount = do
now <- IO CPUTime -> m CPUTime
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CPUTime -> m CPUTime) -> IO CPUTime -> m CPUTime
forall a b. (a -> b) -> a -> b
$ IO CPUTime
forall (m :: * -> *). MonadIO m => m CPUTime
getCPUTime
oldAccount <- getsBenchmark currentAccount
Strict.whenJust oldAccount $ \ (Account (BenchPhase m)
acc, CPUTime
start) ->
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall a b. (a -> b) -> a -> b
$ Account (BenchPhase m)
-> CPUTime -> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
forall a.
Ord a =>
Account a -> CPUTime -> Benchmark a -> Benchmark a
addCPUTime Account (BenchPhase m)
acc (CPUTime -> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> CPUTime -> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
forall a b. (a -> b) -> a -> b
$ CPUTime
now CPUTime -> CPUTime -> CPUTime
forall a. Num a => a -> a -> a
- CPUTime
start
modifyBenchmark $ mapCurrentAccount $ const $ (, now) <$> newAccount
return $ fst <$> oldAccount
reset :: MonadBench m => m ()
reset :: forall (m :: * -> *). MonadBench m => m ()
reset = (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall (m :: * -> *).
MonadBench m =>
(Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
modifyBenchmark ((Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ())
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)) -> m ()
forall a b. (a -> b) -> a -> b
$
(CurrentAccount (BenchPhase m) -> CurrentAccount (BenchPhase m))
-> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
forall a.
(CurrentAccount a -> CurrentAccount a)
-> Benchmark a -> Benchmark a
mapCurrentAccount (CurrentAccount (BenchPhase m)
-> CurrentAccount (BenchPhase m) -> CurrentAccount (BenchPhase m)
forall a b. a -> b -> a
const CurrentAccount (BenchPhase m)
forall a. Maybe a
Strict.Nothing) (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> (Benchmark (BenchPhase m) -> Benchmark (BenchPhase m))
-> Benchmark (BenchPhase m)
-> Benchmark (BenchPhase m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Timings (BenchPhase m) -> Timings (BenchPhase m))
-> Benchmark (BenchPhase m) -> Benchmark (BenchPhase m)
forall a. (Timings a -> Timings a) -> Benchmark a -> Benchmark a
mapTimings (Timings (BenchPhase m)
-> Timings (BenchPhase m) -> Timings (BenchPhase m)
forall a b. a -> b -> a
const Timings (BenchPhase m)
forall a. Null a => a
Trie.empty)
{-# INLINABLE billTo #-}
billTo :: MonadBench m => Account (BenchPhase m) -> m c -> m c
billTo :: forall (m :: * -> *) c.
MonadBench m =>
Account (BenchPhase m) -> m c -> m c
billTo Account (BenchPhase m)
account m c
m = m Bool -> m c -> m c -> m c
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifNotM (Account (BenchPhase m) -> BenchmarkOn (BenchPhase m) -> Bool
forall a. Account a -> BenchmarkOn a -> Bool
isBenchmarkOn Account (BenchPhase m)
account (BenchmarkOn (BenchPhase m) -> Bool)
-> m (BenchmarkOn (BenchPhase m)) -> m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Benchmark (BenchPhase m) -> BenchmarkOn (BenchPhase m))
-> m (BenchmarkOn (BenchPhase m))
forall (m :: * -> *) c.
MonadBench m =>
(Benchmark (BenchPhase m) -> c) -> m c
getsBenchmark Benchmark (BenchPhase m) -> BenchmarkOn (BenchPhase m)
forall a. Benchmark a -> BenchmarkOn a
benchmarkOn) m c
m (m c -> m c) -> m c -> m c
forall a b. (a -> b) -> a -> b
$ do
old <- Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
forall (m :: * -> *).
MonadBench m =>
Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
switchBenchmarking (Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m))))
-> Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
forall a b. (a -> b) -> a -> b
$ Account (BenchPhase m) -> Maybe (Account (BenchPhase m))
forall a. a -> Maybe a
Strict.Just Account (BenchPhase m)
account
(liftIO . E.evaluate =<< m) `finally` switchBenchmarking old
billToCPS :: MonadBench m => Account (BenchPhase m) -> ((b -> m c) -> m c) -> (b -> m c) -> m c
billToCPS :: forall (m :: * -> *) b c.
MonadBench m =>
Account (BenchPhase m) -> ((b -> m c) -> m c) -> (b -> m c) -> m c
billToCPS Account (BenchPhase m)
account (b -> m c) -> m c
f b -> m c
k = m Bool -> m c -> m c -> m c
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifNotM (Account (BenchPhase m) -> BenchmarkOn (BenchPhase m) -> Bool
forall a. Account a -> BenchmarkOn a -> Bool
isBenchmarkOn Account (BenchPhase m)
account (BenchmarkOn (BenchPhase m) -> Bool)
-> m (BenchmarkOn (BenchPhase m)) -> m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Benchmark (BenchPhase m) -> BenchmarkOn (BenchPhase m))
-> m (BenchmarkOn (BenchPhase m))
forall (m :: * -> *) c.
MonadBench m =>
(Benchmark (BenchPhase m) -> c) -> m c
getsBenchmark Benchmark (BenchPhase m) -> BenchmarkOn (BenchPhase m)
forall a. Benchmark a -> BenchmarkOn a
benchmarkOn) ((b -> m c) -> m c
f b -> m c
k) (m c -> m c) -> m c -> m c
forall a b. (a -> b) -> a -> b
$ do
old <- Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
forall (m :: * -> *).
MonadBench m =>
Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
switchBenchmarking (Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m))))
-> Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
forall a b. (a -> b) -> a -> b
$ Account (BenchPhase m) -> Maybe (Account (BenchPhase m))
forall a. a -> Maybe a
Strict.Just Account (BenchPhase m)
account
f $ \ b
x -> b
x b -> m c -> m c
forall a b. a -> b -> b
`seq` do
_ <- Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
forall (m :: * -> *).
MonadBench m =>
Maybe (Account (BenchPhase m))
-> m (Maybe (Account (BenchPhase m)))
switchBenchmarking Maybe (Account (BenchPhase m))
old
k x
billPureTo :: MonadBench m => Account (BenchPhase m) -> c -> m c
billPureTo :: forall (m :: * -> *) c.
MonadBench m =>
Account (BenchPhase m) -> c -> m c
billPureTo Account (BenchPhase m)
account = Account (BenchPhase m) -> m c -> m c
forall (m :: * -> *) c.
MonadBench m =>
Account (BenchPhase m) -> m c -> m c
billTo Account (BenchPhase m)
account (m c -> m c) -> (c -> m c) -> c -> m c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return
instance NFData a => NFData (BenchmarkOn a)
instance NFData a => NFData (Benchmark a)