Path: blob/develop/benchmarking/compareBenchmarkResults.hs
1 views
{-# LANGUAGE TemplateHaskell #-}1{-# LANGUAGE OverloadedStrings #-}23import Control.Arrow4import Control.Lens5import Data.Aeson6import Data.Aeson.TH7import Data.Align8import qualified Data.ByteString.Lazy as LBS9import Data.Either10import Data.Foldable11import qualified Data.Map as Map12import Data.Monoid13import qualified Data.Text as T14import qualified Data.Text.IO as T15import Data.Text (Text)16import Data.These17import System.Environment18import System.FilePath1920data BenchmarkResult = BenchmarkResult21{ _benchmarkResult_framework :: Text22, _benchmarkResult_benchmark :: Text23, _benchmarkResult_type :: Text24, _benchmarkResult_min :: Double25, _benchmarkResult_max :: Double26, _benchmarkResult_mean :: Double27, _benchmarkResult_median :: Double28, _benchmarkResult_geometricMean :: Double29, _benchmarkResult_standardDeviation :: Double30, _benchmarkResult_values :: [Double]31}32deriving (Show, Read, Eq, Ord)3334deriveJSON (defaultOptions { fieldLabelModifier = drop $ length ("_benchmarkResult_" :: String) }) ''BenchmarkResult3536loadResult :: FilePath -> IO [BenchmarkResult]37loadResult p = either error id . eitherDecode <$> LBS.readFile p3839main :: IO ()40main = do41[file1, file2] <- getArgs42results1 <- loadResult file143results2 <- loadResult file244let byFramework = Map.fromListWith (<>) . map (_benchmarkResult_framework &&& pure)45befores = byFramework results146afters = byFramework results247inters = Map.intersectionWith (,) befores afters48traverse_ T.putStrLn $ Map.mapWithKey table inters4950table :: Text -> ([BenchmarkResult], [BenchmarkResult]) -> Text51table framework (before, after) =52let resultMap = Map.fromList . fmap (_benchmarkResult_benchmark &&& _benchmarkResult_geometricMean)53results1 = resultMap before54results2 = resultMap after55showMNum = maybe "?" (T.pack . show)56title = "### " <> framework57header = "| Benchmark | Before | After | Ratio |"58separator = "| --- | --- | --- | --- |"59formatLine (b, rs) =60let r1 = preview here rs61r2 = preview there rs62in "| " <> b <> " | " <> showMNum r1 <> " | " <> showMNum r2 <> " | " <> showMNum ((/) <$> r2 <*> r1) <> " |"63in64T.unlines $ title : header : separator : fmap formatLine (Map.toList $ align results1 results2)656667