{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DataKinds #-}
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Perf.Analysis where
import Data.Scientific
import Data.TDigest
import Formatting
import Perf
import Protolude hiding ((%))
import qualified Data.Text as Text
deciles :: (Functor f, Foldable f, Integral a) => a -> f a -> [Double]
deciles n xs =
(\x -> fromMaybe 0 $
quantile x (tdigest (fromIntegral <$> xs) :: TDigest 25)) <$>
((/ fromIntegral n) . fromIntegral <$> [0 .. n])
percentile :: (Functor f, Foldable f, Integral a) => Double -> f a -> Double
percentile p xs = fromMaybe 0 $ quantile p (tdigest (fromIntegral <$> xs) :: TDigest 25)
prec :: Int -> Format r (Scientific -> r)
prec n = scifmt Exponent (Just n)
int2Sci :: (Integral a) => a -> Scientific
int2Sci n = scientific (fromIntegral n) 0
formatInt :: (Integral a) => Text -> Int -> a -> Text
formatInt label p x =
sformat
((right 24 ' ' %. stext) %
(left 8 ' ' %. prec p)) label (int2Sci x)
formatRun :: (Integral a) => Text -> Int -> [a] -> Text
formatRun label p xs =
sformat
((right 24 ' ' %. stext) % stext %
(left 9 ' ' %. prec p) %
(left 9 ' ' %. prec p))
label
(Text.intercalate " " $ sformat (left 8 ' ' %. prec p) .
int2Sci <$>
take 3 xs)
(fromFloatDigits $ percentile 0.5 xs)
(fromFloatDigits $ average xs)
formatRunHeader :: Text
formatRunHeader =
sformat
((right 24 ' ' %. stext) %
(left 8 ' ' %. stext) %
(left 9 ' ' %. stext) %
(left 9 ' ' %. stext) %
(left 9 ' ' %. stext) %
(left 9 ' ' %. stext))
"run"
"first"
"2nd"
"3rd"
"median"
"av."
formatGap :: (Integral a) => Int -> (a, ([a],b)) -> Text
formatGap a (co, (ci, _)) =
sformat
("n = " %(left 7 ' ' %. prec 3)%" outside: "%(left 7 ' ' %. prec 3)%" inside: "%(left 7 ' ' %. prec 3)%" gap: "%(left 7 ' ' %. prec 3))
(int2Sci a) (int2Sci co) (int2Sci $ sum ci) (int2Sci $ co - sum ci)
code :: [Text] -> Text
code cs = "\n```\n" <> Text.intercalate "\n" cs <> "\n```\n"