packages feed

perf-analysis 0.0.1.1 → 0.1.0.0

raw patch · 4 files changed

+186/−188 lines, 4 filesdep +readme-lhsdep ~base

Dependencies added: readme-lhs

Dependency ranges changed: base

Files

examples/examples.hs view
@@ -13,12 +13,12 @@  module Main where -import Data.Scientific+import Readme.Lhs import Formatting import Options.Generic import Perf import Perf.Analysis-import Protolude hiding ((%))+import Protolude import qualified Data.Map as Map import qualified Data.Text as Text import qualified Data.Vector as V@@ -63,15 +63,6 @@   let !n = fromMaybe 1000 (runs o)   let !a = fromMaybe 1000 (sumTo o)   let !as = [1, 10, 100, 1000 :: Int]--  writeFile "other/run.md" $-    code-      [ formatInt "number of runs:" 2 n-      , formatInt "accumulate to:" 2 a-      , sformat ((right 24 ' ' %. stext)%stext) "function:" "foldl' (+) 0"-      ]--  -- | tick_ testing   prewarmup <- tick_   _ <- warmup 100   onetick <- tick_@@ -83,20 +74,34 @@   let tick99999 = percentile 0.99999 manyticks   let tick99 = percentile 0.99 manyticks   let tick40 = percentile 0.4 manyticks-  writeFile "other/tick_.md" $-    code-      [ "pre warmup: " <> show prewarmup <> " cycles"-      , "one tick_: " <> show onetick <> " cycles"-      , "next 10: " <> show ticks'-      , "average over 1m: " <> sformat (fixed 2) avticks <> " cycles"-      , "99.999% perc: " <> sformat commas (floor tick99999 :: Integer)-      , "99.9% perc: " <> sformat (fixed 2) tick999-      , "99th perc:  " <> sformat (fixed 2) tick99-      , "40th perc:  " <> sformat (fixed 2) tick40-      , "[min, 20th, .. 80th, max]:"-      , mconcat (sformat (" " % prec 4) . fromFloatDigits <$> qticks)-      ] +  -- perf basics+  (result, cs) <- runPerfT $+      perf "sum" cycles (pure $ foldl' (+) 0 [0 .. a])+  putStrLn (show (result, cs) :: Text)++  -- PerfT example+  -- prior to Perfification+  result <- do+      txt <- readFile "perf-analysis/examples/examples.hs"+      let n = Text.length txt+      let x = foldl' (+) 0 [1..n]+      putStrLn $ "sum of one to number of characters is: " <>+          (show x :: Text)+      pure (n, x)++  -- post-Perfification+  (result', ms) <- runPerfT $ do+          txt <- perf "file read" cycles $ readFile "perf-analysis/examples/examples.hs"+          n <- perf "length" cycles $ pure (Text.length txt)+          x <- perf "sum" cycles $ pure (foldl' (+) 0 [1..n])+          perf "print to screen" cycles $+              putStrLn $ "sum of one to number of characters is: " <>+              (show x :: Text)+          pure (n, x)++  when (result == result') $ print "PerfT has no effect on original computation"+   -- | tick tests   (t, resultPrime) <- tick fMono a   print resultPrime@@ -111,20 +116,6 @@   t10io <- sequence $ replicate 10 (tickIO $ pure (fMono a))   -- t10n <- sequence $ replicate 10 (tickNoinline fMono a)   t10' <- sequence $ replicate 10 (tick fMono a)-  writeFile "other/tick.md" $-    code-      [ "sum to " <> show a-      , "first measure: " <> show t <> " cycles"-      , "second measure: " <> show t2 <> " cycles"-      , "third measure: " <> show t3 <> " cycles"-      , "tick': " <> show t' <> " cycles"-      , "tickIO: " <> show tio <> " cycles"-      -- , "tickNoinline: " <> show tn <> " cycles"-      , "tick * 10: " <> show (fst <$> t10)-      , "tickIO * 10: " <> show (fst <$> t10io)-      -- , "tickNoinline * 10: " <> show (fst <$> t10n)-      , "tick * 10: " <> show (fst <$> t10')-      ]    -- | ticks and ticksIO   (rpure, _) <- ticks n fMono a@@ -134,35 +125,14 @@   (rioPoly, _) <- ticksIO n (pure $ fPoly a)   (rioLambda, _) <- ticksIO n (pure $ fLambda a) -  writeFile "other/ticks.md" $-    code [ "acc = " <> show a <> " n = " <> show n-         , formatRunHeader-         , formatRun "monomorphic" 2 $ rpure-         , formatRun "includes lambda" 2 $ rpureLambda-         , formatRun "polymorphic" 2 $ rpurePoly-         , formatRun "ticksIO mono" 2 $ rio-         , formatRun "ticksIO lambda" 2 $ rioLambda-         , formatRun "ticksIO poly" 2 $ rioPoly-         ]--  gaps <- sequence $ (\a -> formatGap a <$> tickIO (ticks n fPoly a)) <$> as-  writeFile "other/ticksCost.md" $ code gaps+  -- | gaps+  gaps <- sequence $ (tickIO . ticks n fPoly) <$> as    -- | ns testing   css <-     fmap (fmap fst) <$>     sequence ((replicateM n . tick fMono) <$> as)-  let r12 =-        "(replicateM n . tick fMono) <$> as: " <>-        mconcat (sformat (" " %prec 3) <$>-                 (fromFloatDigits . percentile 0.4 <$> css))   (ts, _) <- ns (ticks n fMono) as-  let r13 =-        "ns (ticks n fMono) as: " <>-        mconcat (sformat (" " %prec 3) <$>-                 (fromFloatDigits . percentile 0.4 <$> ts))-  writeFile "other/tickns.md" $-    code ["sum to's " <> show as, r13, r12]    -- | vectors   let asl :: [Int]@@ -185,14 +155,6 @@   let asu :: U.Vector Int =         U.generate a identity   (runboxed, _) <- ticks n sumu asu-  writeFile "other/vector.md" $-    code-    [ "sum to " <> show a-    , formatRun "ticks list" 2 $ rlist-    , formatRun "ticks boxed" 2 $ rboxed-    , formatRun "ticks storable" 2 $ rstorable-    , formatRun "ticks unboxed" 2 $ runboxed-    ]    -- WHNF   (rnf, _) <- tick (fmap fMono) (Just a)@@ -204,47 +166,101 @@   (rnfsio, _) <- ticksIO n (pure $ fmap fMono (Just a))   (rwhnfsio, _) <- ticksWHNFIO n (pure $ fmap fMono (Just a)) -  writeFile "other/whnf.md" $ code-    [ "sum to " <> show a-    , formatInt "tick" 2 $ rnf-    , formatInt "tickWHNF" 2 $ rwhnf-    , formatRun "ticks" 2 rnfs-    , formatRun "ticksWHNF" 2 rwhnfs-    , formatInt "tickIO" 2 rnfio-    , formatInt "tickWHNFIO" 2 rwhnfio-    , formatRun "ticksIO" 2 rnfsio-    , formatRun "ticksWHNFIO" 2 rwhnfsio-    ]+  void $ runOutput+    ("other/readme_.md", GitHubMarkdown)+    ("readme.md", GitHubMarkdown) $ do -  -- perf basics-  (result, cs) <- runPerfT $-      perf "sum" cycles (pure $ foldl' (+) 0 [0 .. a])-  putStrLn (show (result, cs) :: Text)+    output "run" $ Native $ (:[]) $ table+      "run details"+      []+      [AlignLeft, AlignRight]+      [0, 0]+      [ ["number of runs", formatI 2 n]+      , ["accumulate to", formatI 2 a]+      , ["function", "foldl' (+) 0"]+      ] -  -- PerfT example-  -- prior to Perfification-  result <- do-      txt <- readFile "perf-analysis/examples/examples.hs"-      let n = Text.length txt-      let x = foldl' (+) 0 [1..n]-      putStrLn $ "sum of one to number of characters is: " <>-          (show x :: Text)-      pure (n, x)+    output "tick_" $ Native $ (:[]) $ table mempty ["stat", "cycles"] mempty mempty+      [ ["pre warmup", show prewarmup]+      , ["one tick_", show onetick]+      , ["next 10", show ticks']+      , ["average over one million", sformat (fixed 2) avticks]+      , ["99.999% perc", sformat commas (floor tick99999 :: Integer)]+      , ["99.9% perc", sformat (fixed 2) tick999]+      , ["99th perc", sformat (fixed 2) tick99]+      , ["40th perc", sformat (fixed 2) tick40]+      , ["[min, 20th, .. 80th, max]",+         Text.intercalate " " (formatF 4 <$> qticks)]+      ] -  -- post-Perfification-  (result', ms) <- runPerfT $ do-          txt <- perf "file read" cycles $ readFile "perf-analysis/examples/examples.hs"-          n <- perf "length" cycles $ pure (Text.length txt)-          x <- perf "sum" cycles $ pure (foldl' (+) 0 [1..n])-          perf "print to screen" cycles $-              putStrLn $ "sum of one to number of characters is: " <>-              (show x :: Text)-          pure (n, x)+    output "tick" $ Native+      [ plain ("sum to " <> show a)+      , table mempty ["stat", "cycles"] mempty mempty+        [ ["first measure", show t]+        , ["second measure", show t2]+        , ["third measure", show t3]+        , ["tick'", show t']+        , ["tickIO", show tio]+        , ["tick * 10", show (fst <$> t10)]+        , ["tickIO * 10", show (fst <$> t10io)]+        , ["tick' * 10", show (fst <$> t10')]+        ]+      ] -  when (result == result') $ print "PerfT has no effect on original computation"+    output "ticks" $ Native [formatRuns 3 2+      [ ("monomorphic", rpure)+      , ("includes lambda", rpureLambda)+      , ("polymorphic", rpurePoly)+      , ("ticksIO mono", rio)+      , ("ticksIO lambda", rioLambda)+      , ("ticksIO poly", rioPoly)+      ]] -  let fmt = sformat ((right 40 ' ' %. stext) %prec 3 % " " % stext)-  writeFile "other/perf.md" $-    "\nperf cycle measurements\n---\n" <>-    code ((\(t,c) -> fmt t (int2Sci c) "cycles") <$> Map.toList ms) ++    output "gaps" $ Native $ (:[]) $ table mempty+      ["number runs", "outside cycles", "inside cycles", "gap"]+      mempty mempty+      (zipWith (\a (co, (ci, _)) ->+                  [ formatI 1 a+                  , formatI 3 co+                  , formatI 3 (sum ci)+                  , formatI 3 (co - sum ci)+                  ]) as gaps)++    output "tickns" $ Native+      [ table mempty (["sum to:"] <> (show <$> as)) mempty mempty+        [ ["(replicateM n . tick fMono) <$> as"] <>+          (formatF 3 . percentile 0.5 <$> css)+        , ["ns (ticks n fMono) as"] <>+          (formatF 3 . percentile 0.5 <$> ts)+        ]+      ]++    output "vector" $ Native $ [plain ("sum to " <> show a)] <>+      [formatRuns 3 2 +      [ ("ticks list", rlist)+      , ("ticks boxed", rboxed)+      , ("ticks storable", rstorable)+      , ("ticks unboxed", runboxed)+      ]]++    output "whnf" $ Native+      [ plain ("sum to " <> show a)+      , table mempty ["function", "cycles"] mempty mempty+        [ ["tick", formatI 3 rnf]+        , ["tickWHNF", formatI 3 rwhnf]+        , formatRun "ticks" 3 3 rnfs+        , formatRun "ticksWHNF" 3 3 rwhnfs+        , ["tickIO", formatI 3 rnfio]+        , ["tickWHNFIO", formatI 3 rwhnfio]+        , formatRun "ticksIO" 3 3 rnfsio+        , formatRun "ticksWHNFIO" 3 3 rwhnfsio+        ]+      ]++    output "perf" $ Native+      [ plain "perf cycle measurements"+      , table mempty ["effect", "cycles"] mempty mempty+        ((\(t,c) -> [t, formatI 3 c]) <$> Map.toList ms)+      ]
perf-analysis.cabal view
@@ -1,11 +1,5 @@--- This file has been generated from package.yaml by hpack version 0.28.2.------ see: https://github.com/sol/hpack------ hash: 5b2bb96e01227ec3ddd4c29e4bebf5895c909acff05541ea597f16b063ce3eb4- name:           perf-analysis-version:        0.0.1.1+version:        0.1.0.0 synopsis:       analysis example using perf description:     Analytical tools to use with perf.  category:       performance@@ -17,9 +11,7 @@ license:        BSD3 license-file:   LICENSE build-type:     Simple-cabal-version:  >= 1.10-extra-source-files:-    stack.yaml+cabal-version:  2.0  source-repository head   type: git@@ -29,12 +21,10 @@ library   exposed-modules:       Perf.Analysis-  other-modules:-      Paths_perf_analysis   hs-source-dirs:       src   build-depends:-      base >=4.7 && <4.12+      base >=4.7 && <5     , deepseq     , formatting     , perf >=0.4.1.0@@ -43,17 +33,16 @@     , tdigest     , text     , vector+    , readme-lhs   default-language: Haskell2010  executable perf-examples   main-is: examples.hs-  other-modules:-      Paths_perf_analysis   hs-source-dirs:       examples   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -rtsopts -O2   build-depends:-      base >=4.7 && <4.12+      base >=4.7 && <5     , containers     , deepseq     , formatting@@ -65,4 +54,5 @@     , tdigest     , text     , vector+    , readme-lhs   default-language: Haskell2010
src/Perf/Analysis.hs view
@@ -1,14 +1,7 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE NoImplicitPrelude #-} {-# 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 #-}  -- | analytical functionality for perf module Perf.Analysis where@@ -17,8 +10,8 @@ import Data.TDigest import Formatting import Perf-import Protolude hiding ((%))-import qualified Data.Text as Text+import Protolude+import Readme.Lhs hiding (Format)  -- | compute deciles --@@ -55,51 +48,61 @@ int2Sci :: (Integral a) => a -> Scientific int2Sci n = scientific (fromIntegral n) 0 --- | format an Integral as a Scientific with a label and precision-formatInt :: (Integral a) => Text -> Int -> a -> Text-formatInt label p x =-        sformat-          ((right 24 ' ' %. stext) %-           (left 8 ' ' %. prec p)) label (int2Sci x)+formatSecs :: (RealFloat a) => Int -> a -> Text+formatSecs p s+    | s < 0      = "-" <> formatSecs p (-s)+    | s >= 1     = formatFixed p s <> " s"+    | s >= 1e-3  = formatFixed p (s*1e3) <> " ms"+    | s >= 1e-6  = formatFixed p (s*1e6)  <> " μs"+    | s >= 1e-9  = formatFixed p (s*1e9) <> " ns"+    | otherwise  = formatFixed p (s*1e12) <> " ps" --- | format the first 5 results, and then the 40th percentile-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)+-- | format an Integral as a Scientific with a precision+formatI :: (Integral a) => Int -> a -> Text+formatI p x = sformat (prec p) (int2Sci x) --- | header for formatRun-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."+-- | format a Float as a Scientific with a precision+formatF :: (RealFloat a) => Int -> a -> Text+formatF p x = sformat (prec p) (fromFloatDigits x) --- | format a tick result with an inside and outside measurement-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)+-- | format a Float as a Scientific with a precision+formatFixed :: (RealFloat a) => Int -> a -> Text+formatFixed p x = sformat (fixed p) (fromFloatDigits x) --- | place markdown backtics around text-code :: [Text] -> Text-code cs = "\n```\n" <> Text.intercalate "\n" cs <> "\n```\n"+-- | format the first few results, the median and average+formatRun :: (Integral a) => Text -> Int -> Int -> [a] -> [Text]+formatRun label n p xs =+  [ label] <>+  (formatI p <$> take n xs) <>+  [ formatF p $ average xs+  , formatF p $ percentile 0.5 xs+  ]++-- | average and time+formatRunTime :: (Integral a) => Text -> Double -> Int -> [a] -> [Text]+formatRunTime label npc p xs =+  [ label] <>+  [ formatF p $ npc * average xs+  , formatF p $ average xs+  ]++formatRuns :: (Integral a) => Int -> Int -> [(Text, [a])] -> Block+formatRuns n p runs =+  table+  mempty+  (["run"] <>+   take n (["first", "second", "third"] <> ((<>"th") . show <$> [4::Int ..])) <>+    ["average", "median"])+  ([AlignLeft] <> replicate (n+2) AlignRight)+  (replicate (n+3) 0)+  (fmap (\(l,as) -> formatRun l n p as) runs)++formatRunsTime :: (Integral a) => Double -> Int -> [(Text, [a])] -> Block+formatRunsTime npc p runs =+  table+  mempty+  ["run", "cputime", "cycles"]+  [AlignLeft, AlignRight, AlignRight]+  []+  (fmap (\(l,as) -> formatRunTime l npc p as) runs)+
− stack.yaml
@@ -1,11 +0,0 @@-resolver: nightly-2018-05-28--packages:-  - .-  - ../perf--extra-deps:-  - rdtsc-1.3.0.1-  - tdigest-0.2--allow-newer: true