packed-data-0.1.0.2: benchmark/report/Criterion.hs
module Criterion where
import Data.Char (isDigit)
import Data.List (isInfixOf, isPrefixOf, isSuffixOf)
import Data.Scientific
import Debug.Trace (trace)
import System.Directory (removeFile)
import System.Process
import Text.Read (readMaybe)
import Types
runCriterionBenchmarks :: BenchSuite -> IO BenchmarkResults
runCriterionBenchmarks s = do
(_, _, _, h) <- createProcess (shell criterionCmd)
_ <- waitForProcess h
csv <- readFile reportPath
res <- parseCSV s csv
removeFile reportPath
return res
where
reportPath = "report.csv"
criterionTestSuiteName = suiteToCriterionBenchName s
criterionCmd =
"cabal bench tree-bench --benchmark-options='--csv "
++ reportPath
++ " "
++ criterionTestSuiteName
++ "'"
suiteToCriterionBenchName :: BenchSuite -> String
suiteToCriterionBenchName = \case
AST -> "ast"
Sum -> "sum"
RightMost -> "traversals/right-most"
Incr -> "increment"
parseCSV :: BenchSuite -> String -> IO BenchmarkResults
parseCSV s csv = do
let cleanCSV = drop 1 $ lines csv
res <- parseCSVForCase cleanCSV s `mapM` cases
return $ filter (not . null . values) res
parseCSVForCase :: [String] -> BenchSuite -> (String, String, Maybe String) -> IO BenchmarkResult
parseCSVForCase csvLines s (caseId, lang, subtitle) = do
let caseLines = filter (('/' : caseId ++ ",") `isInfixOf`) csvLines
caseValues <- parseCSVLineForCase `mapM` caseLines
return $ BenchmarkResult s lang subtitle caseValues
parseCSVLineForCase :: (MonadFail m) => String -> m (Int, Double)
parseCSVLineForCase line =
let res = do
treeSize <- readMaybe rawTreeSize
time <- readMaybe rawTime :: Maybe Scientific
return (treeSize, toRealFloat time)
in trace (show res) $ maybe (fail "Parsing error") return res
where
rawTime =
takeWhile (/= ',') $
drop 1 $
dropWhile (/= ',') line
rawTreeSize =
takeWhile isDigit $
dropWhile (not . isDigit) line
cases :: [(String, String, Maybe String)]
cases =
[ ("c-inplace", "C", Just "Inplace")
, ("c-new-tree", "C", Just "Produces new tree")
, ("native", "Haskell", Nothing)
, ("packed", "packed-data", Just "W/o Indirections")
, ("packed-with-size", "packed-data", Just "W/ Indirections")
, ("packed-unpacked", "packed-data", Just "Unpacking, then traverse")
, ("non-monadic-packed", "packed-data", Just "Non-monadic, w/o Indirections")
, ("non-monadic-packed-with-size", "packed-data", Just "Non-monadic, w/ Indirections")
, ("packed-needsbuilder", "packed-data", Just "Using NeedsBuilder")
, ("unpack-repack", "packed-data", Just "Unpacking, increment and repack")
, ("packed-rebuild-repack", "packed-data", Just "Deserialise and increment, and repack")
]