{-# LANGUAGE FlexibleContexts #-} module Main where import Data.Char (isSpace) import Data.List.Split (splitOn) import Data.Maybe (catMaybes) import System.Exit (ExitCode(..)) import System.Process.Typed (readProcess) import BenchGraph (bgraph, defaultConfig, Config(..), ComparisonStyle(..)) import WithCli (withCli) import Data.List import qualified Data.Text.Lazy as T import qualified Data.Text.Lazy.Encoding as T -- pairs of benchmark group titles and corresponding list of benchmark -- prefixes i.e. without the package name at the end. charts :: [(String, [String])] charts = [ -- Operations are listed in increasing cost order {- ( "Key Operations" , [ "elimination/fold" , "transformation/mapM" , "filtering/filter-even" , "zip" ] ) , -} ( "Append Operation" , [ "append" ] ) , ( "Key Operations" , [ "elimination/drain" , "filtering/drop-all" -- , "filtering/dropWhile-true" -- , "filtering/filter-all-out" , "elimination/last" , "elimination/fold" -- "filtering/take-one" , "transformation/map" , "filtering/take-all" --, "filtering/takeWhile-true" -- , "filtering/filter-all-in" , "filtering/filter-even" , "transformation/scan" , "transformation/mapM" , "zip" -- , "transformation/concat" ] ) , ( "toList Operation" , [ "elimination/toList" ] ) , ( "Composed Operations: 4 times" , [ "compose/mapM" , "compose/all-in-filters" , "compose/map-with-all-in-filter" ] ) ] ------------------------------------------------------------------------------- -- returns [(packagename, version)] getPkgVersions :: [String] -> IO [(String, String)] getPkgVersions packages = do (ecode, out, _) <- readProcess "stack --system-ghc list-dependencies --bench" case ecode of ExitSuccess -> do -- Get our streaming packages and their versions let match [] = Nothing match (_ : []) = Nothing match (x : y : _) = case elem x packages of False -> Nothing True -> Just (x, y) in return $ catMaybes $ map match $ map words (lines (T.unpack $ T.decodeUtf8 out)) ExitFailure _ -> do putStrLn $ "Warning! Cannot determine package versions, " ++ "the 'stack list-dependencies' command failed." return [] -- suffix versions to packages suffixVersion :: [(String, String)] -> String -> String suffixVersion pkginfo p = case lookup p pkginfo of Nothing -> p Just v -> p ++ "-" ++ v createCharts :: String -> String -> Bool -> IO () createCharts input pkgList delta = do let packages = splitOn "," pkgList let pkgInfo = [] -- pkgInfo <- getPkgVersions let cfg (title, prefixes) = defaultConfig { chartTitle = Just title , outputDir = "charts" , comparisonStyle = if delta then CompareDelta else CompareFull , classifyBenchmark = \bm -> case any (`isPrefixOf` bm) prefixes of True -> let xs = reverse (splitOn "/" bm) grp = xs !! 0 bench = xs !! 1 in case grp `elem` packages of True -> Just (suffixVersion pkgInfo grp, bench) False -> Nothing False -> Nothing , sortBenchmarks = \bs -> let i = intersect (map (last . splitOn "/") prefixes) bs in i ++ (bs \\ i) , sortBenchGroups = \gs -> let i = intersect (map (suffixVersion pkgInfo) packages) gs in i ++ (gs \\ i) } -- links in README.rst eat up the space so we match the same let toOutfile title field = (filter (not . isSpace) (takeWhile (/= '(') title)) ++ "-" ++ field makeOneGraph infile field (title, prefixes) = do let title' = title ++ " (" ++ field ++ ")" ++ " (Lower is Better)" bgraph infile (toOutfile title field) field (cfg (title', prefixes)) mapM_ (makeOneGraph input "time") charts mapM_ (makeOneGraph input "allocated") charts mapM_ (makeOneGraph input "maxrss") charts -- Pass main :: IO () main = withCli createCharts