Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmarks #1673

Merged
merged 38 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4f41e04
implement basic benchmarks
janmasrovira Dec 18, 2022
a7ad2ff
smaller input for mergesort
janmasrovira Dec 18, 2022
8a38ae4
wip
janmasrovira Dec 19, 2022
7b22b9d
fix c benchmarks
janmasrovira Dec 20, 2022
fae5da9
Refactor hie.yaml and add entry in the readme (#1672)
janmasrovira Dec 20, 2022
d0a3683
add Juivix.Prelude.Env
janmasrovira Dec 20, 2022
bd09ff5
add benchmark suites
janmasrovira Dec 20, 2022
4d1f827
make fibonacci inpput smaller
janmasrovira Dec 20, 2022
0e744d9
make mergesort input smaller
janmasrovira Dec 20, 2022
a20c042
fix some paths
janmasrovira Dec 20, 2022
19037b0
swap build command for ocaml
janmasrovira Dec 21, 2022
57f3251
match core/mergesort input size with others
janmasrovira Dec 21, 2022
5c6cbe2
fix executable path
janmasrovira Dec 21, 2022
354fda8
automatize plots
janmasrovira Dec 21, 2022
c8174e2
add gnuplot script
janmasrovira Dec 21, 2022
5f0c40e
produce svg
janmasrovira Dec 21, 2022
2b32530
use fixed colours
janmasrovira Dec 21, 2022
7ff05df
use nicer colors and add stddev plot
janmasrovira Dec 22, 2022
69d7fc7
add suites
janmasrovira Dec 22, 2022
7c888b2
Revert "make mergesort input smaller"
janmasrovira Dec 22, 2022
798dce1
Revert "make fibonacci inpput smaller"
janmasrovira Dec 22, 2022
94b6512
revert input changes
janmasrovira Dec 22, 2022
4cb930a
do not use core
janmasrovira Dec 22, 2022
2d85fa4
percentual stddev
janmasrovira Dec 23, 2022
5c642ea
wip
janmasrovira Jan 3, 2023
1d0dad7
switch to criterion
janmasrovira Jan 3, 2023
045ec4b
Change syntax for ind. data types and forbid the empty data type (#1684)
jonaprieto Jan 3, 2023
3d690c2
Remove unicode cons symbol (#1687)
lukaszcz Jan 3, 2023
5b2bc8e
Merge branch 'main' into benchmarks
janmasrovira Jan 3, 2023
d92b71e
add Makefile entry for Jonathan
janmasrovira Jan 3, 2023
95eea10
fix makefile
janmasrovira Jan 3, 2023
3baf00f
adjust offset and size
janmasrovira Jan 3, 2023
724590e
drop pdf output
janmasrovira Jan 3, 2023
494bf7b
Convert Nat literals to Core integers (#1681)
lukaszcz Jan 3, 2023
da8a34a
Merge branch 'main' into benchmarks
janmasrovira Jan 3, 2023
5798098
add missing suites
janmasrovira Jan 5, 2023
f9fe818
Merge branch 'main' into benchmarks
janmasrovira Jan 5, 2023
db28f2a
Merge branch 'main' into benchmarks
janmasrovira Jan 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,5 @@ docs/org/README.org
# Binary files (produced by `make check`)
examples/milestone/HelloWorld/HelloWorld
hie.yaml
/.shake/
/.benchmark-results/
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,7 @@ test-shell : install
changelog-updates :
@github_changelog_generator
@pandoc CHANGELOG.md --from markdown --to org -o UPDATES-FOR-CHANGELOG.org

.PHONY : bench
bench: runtime submodules
@stack bench
122 changes: 122 additions & 0 deletions bench/Base.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
module Base where

import Data.Colour
import Data.Colour.SRGB
import Development.Shake hiding ((<//>))
import Juvix.Extra.Paths
import Juvix.Prelude
import Prelude (Show (show))

root :: Path Abs Dir
root = relToProject $(mkRelDir "tests/benchmark")

resultsDir :: Path Abs Dir
resultsDir = relToProject $(mkRelDir ".benchmark-results")

resultDirs :: [Path Abs Dir]
resultDirs = [binDir, plotDir, csvDir]

binDir :: Path Abs Dir
binDir = resultsDir <//> $(mkRelDir "bin")

plotDir :: Path Abs Dir
plotDir = resultsDir <//> $(mkRelDir "plot")

csvDir :: Path Abs Dir
csvDir = resultsDir <//> $(mkRelDir "csv")

-- | e.g. 0xf0f8ff (format supported by gnuplot)
showColour :: Colour Double -> Text
showColour = pack . ("0x" <>) . dropExact 1 . sRGB24show

data Lang
= Ocaml
| Haskell
| C
| Juvix
| Runtime
| Core
deriving stock (Eq)

instance Show Lang where
show = \case
Ocaml -> "ocaml"
Haskell -> "haskell"
C -> "c"
Juvix -> "juvix"
Runtime -> "runtime"
Core -> "core"

langPath :: Lang -> Path Rel Dir
langPath = relDir . Prelude.show

langFile :: Lang -> Path Rel File
langFile = relFile . Prelude.show

langExtension :: Lang -> String
langExtension = \case
Ocaml -> ".ml"
Haskell -> ".hs"
C -> ".c"
Juvix -> ".juvix"
Runtime -> ".c"
Core -> ".jvc"

data Variant = Variant
{ _variantTitle :: Maybe String,
_variantLanguage :: Lang,
_variantExtensions :: [String],
_variantColor :: Colour Double,
_variantRun :: Path Abs File -> IO (),
_variantBuild :: BuildArgs -> Action ()
}

data BuildArgs = BuildArgs
{ _buildSrc :: Path Abs File,
_buildOutDir :: Path Abs Dir
}

data Suite = Suite
{ _suiteTitle :: String,
_suiteVariants :: [Variant]
}

makeLenses ''Suite
makeLenses ''BuildArgs
makeLenses ''Variant

gnuplotFile :: Path Abs File
gnuplotFile = relToProject $(mkRelFile "gnuplot/bars.gp")

suitePlotFile :: Suite -> Path Abs File
suitePlotFile s = plotDir <//> suiteBaseFile s

suitePdfFile :: Suite -> Path Abs File
suitePdfFile s = addExtension' ".pdf" (suitePlotFile s)

suiteSvgFile :: Suite -> Path Abs File
suiteSvgFile s = addExtension' ".svg" (suitePlotFile s)

suiteCsvFile :: Suite -> Path Abs File
suiteCsvFile s = addExtension' ".csv" (csvDir <//> suiteBaseFile s)

suiteSrcDir :: Suite -> Path Abs Dir
suiteSrcDir s = root <//> relDir (s ^. suiteTitle)

suiteBaseFile :: Suite -> Path Rel File
suiteBaseFile s = relFile (s ^. suiteTitle)

variantSrcDir :: Suite -> Variant -> Path Abs Dir
variantSrcDir s v = suiteSrcDir s <//> langPath (v ^. variantLanguage)

suitePath :: Suite -> Path Rel Dir
suitePath s = relDir (s ^. suiteTitle)

variantBinDir :: Suite -> Variant -> Path Abs Dir
variantBinDir s v = binDir <//> suitePath s <//> langPath (v ^. variantLanguage)

variantBinFile :: Suite -> Variant -> Path Abs File
variantBinFile s v = variantBinDir s v <//> addExtensions' (v ^. variantExtensions) (suiteBaseFile s)

binFile :: BuildArgs -> [String] -> Path Abs File
binFile args ext = args ^. buildOutDir <//> replaceExtensions' ext (filename (args ^. buildSrc))
124 changes: 124 additions & 0 deletions bench/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
module Main where

import Base
import Criterion.Main
import Criterion.Main.Options hiding (config)
import Criterion.Types
import Data.Text qualified as Text
import Development.Shake hiding ((<//>))
import Juvix.Prelude.Base
import Juvix.Prelude.Path as Path hiding (doesFileExist, (-<.>))
import Juvix.Prelude.Path qualified as Path
import Statistics.Types
import Suites

main :: IO ()
main = shakeArgs opts compileRules
where
opts :: ShakeOptions
opts = shakeOptions

compileRules :: Rules ()
compileRules = do
phony "clean" $ do
putInfo ("Deleting " <> toFilePath resultsDir)
removePathForcibly resultsDir
forM_ suites suiteRules

suiteRules :: Suite -> Rules ()
suiteRules s = do
forM_ (s ^. suiteVariants) (variantRules s)
csvRules s
plotRules s

multiRecipe :: [Path Abs File] -> Action () -> Rules ()
multiRecipe out howto = map toFilePath out &%> const howto

recipe :: Path Abs File -> Action () -> Rules ()
recipe out howto = toFilePath out %> const howto

variantRules :: Suite -> Variant -> Rules ()
variantRules s v = do
action $ do
whenM
(doesFileExist (toFilePath srcFile))
(need [toFilePath exeFile])

recipe exeFile $ do
need [toFilePath srcFile]
ensureDir outDir
(v ^. variantBuild) args
where
args :: BuildArgs
args =
BuildArgs
{ _buildSrc = srcFile,
_buildOutDir = outDir
}
lang :: Lang
lang = v ^. variantLanguage
srcFile :: Path Abs File
srcFile =
addExtension'
(langExtension lang)
(suiteSrcDir s <//> langPath lang <//> suiteBaseFile s)
exeFile :: Path Abs File
exeFile = outDir <//> replaceExtensions' (v ^. variantExtensions) (filename srcFile)
outDir :: Path Abs Dir
outDir = variantBinDir s v

plotRules :: Suite -> Rules ()
plotRules s = do
let csv :: Path Abs File = suiteCsvFile s
svg :: Path Abs File = suiteSvgFile s
out :: Path Abs File = suitePlotFile s
want [toFilePath svg]
multiRecipe [svg] $ do
need [toFilePath csv, toFilePath gnuplotFile]
ensureDir (parent svg)
command_
[]
"gnuplot"
( gpArg "name" (s ^. suiteTitle)
++ gpArg "outfile" (toFilePath out)
++ gpArg "csvfile" (toFilePath csv)
++ [toFilePath gnuplotFile]
)
where
gpArg :: String -> String -> [String]
gpArg arg val = ["-e", arg <> "='" <> val <> "'"]

csvRules :: Suite -> Rules ()
csvRules s =
recipe csv $ do
need [toFilePath (variantBinFile s v) | v <- s ^. suiteVariants]
ensureDir (parent csv)
whenM (Path.doesFileExist csv) (removeFile csv)
liftIO (runMode (Run (config s) Glob []) (fromSuite s) >> addColorColumn)
where
csv :: Path Abs File = suiteCsvFile s
addColorColumn :: IO ()
addColorColumn = do
header :| rows <- nonEmpty' . Text.lines <$> readFile (toFilePath csv)
let rows' =
[ showColour (v ^. variantColor) <> "," <> r
| (v, r) <- zipExact (s ^. suiteVariants) rows
]
header' = "Color," <> header
writeFile (toFilePath csv) (Text.unlines (header' : rows'))

fromSuite :: Suite -> [Benchmark]
fromSuite s = map go (s ^. suiteVariants)
where
go :: Variant -> Benchmark
go v = bench title (nfIO ((v ^. variantRun) (variantBinFile s v)))
where
title :: String
title = show (v ^. variantLanguage) <> maybe "" (" " <>) (v ^. variantTitle)

config :: Suite -> Config
config s =
defaultConfig
{ csvFile = Just (toFilePath (suiteCsvFile s)),
confInterval = cl90
}
28 changes: 28 additions & 0 deletions bench/Suites.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Suites where

import Base
import Juvix.Prelude
import Variants

suites :: [Suite]
suites =
map
defaultSuite
[ "mergesort",
"fibonacci",
"maybe"
]
<> [ Suite suiteName (allVariantsExcept [C] [CoreEval])
| suiteName <- ["fold", "mapfold"]
]
<> [Suite "mapfun" (allVariantsExcept [C] [CoreEval, JuvixExe, JuvixWasm])]
<> [ Suite suiteName (allVariantsExcept [] [CoreEval, JuvixExe, JuvixWasm])
| suiteName <- ["ackermann", "combinations", "cps", "prime"]
]

lukaszcz marked this conversation as resolved.
Show resolved Hide resolved
defaultSuite :: String -> Suite
defaultSuite title =
Suite
{ _suiteTitle = title,
_suiteVariants = defaultVariants
}
Loading