cli: a more robust and featureful bench test
The bench script invoked by cabal bench or stack bench now links the benchmarked code directly, avoiding any dependence on the shell and $PATH. Also, it reports the journal parse time and the various reports on the parsed data separately, and runs quicker. You can get more accurate benchmark times by running with --criterion. This will usually give much the same numbers and takes much longer. Benchmarking via simplebench is still available, by running with --simplebench. In this mode it benchmarks whatever commands are configured in bench/default.bench. A disadvantage is that it uses the first "hledger" executable in $PATH, so check which one it reports.
This commit is contained in:
parent
206887db43
commit
01db48fcfc
@ -1,15 +1,79 @@
|
||||
-- bench
|
||||
-- By default, show approximate times for some standard hledger operations on a sample journal.
|
||||
-- With --criterion, show accurate times (slow).
|
||||
-- With --simplebench, show approximate times for the commands in default.bench, using the first hledger executable on $PATH.
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Criterion.Main (defaultMainWith, defaultConfig, bench, nfIO)
|
||||
-- import Criterion.Types
|
||||
import SimpleBench (defaultMain)
|
||||
import System.Environment (withArgs)
|
||||
import System.Directory (getCurrentDirectory)
|
||||
import System.Environment (getArgs, withArgs)
|
||||
import System.Info (os)
|
||||
-- import System.IO (hFlush, stdout)
|
||||
import System.Process (readProcess)
|
||||
import System.TimeIt (timeItT)
|
||||
import Text.Printf
|
||||
import Hledger.Cli
|
||||
|
||||
-- sample journal file to use for benchmarks
|
||||
inputfile = "bench/10000x1000x10.journal"
|
||||
|
||||
outputfile = "/dev/null" -- hide output of benchmarked commands (XXX unixism)
|
||||
-- outputfile = "-" -- show output of benchmarked commands
|
||||
|
||||
-- a delay to avoid truncation of final output by "stack bench"
|
||||
-- https://github.com/commercialhaskell/stack/issues/413
|
||||
stackFinalOutputDelaySeconds = 0 -- 10
|
||||
|
||||
main = do
|
||||
-- expects to be run from the parent directory, as by cabal
|
||||
withArgs [
|
||||
"-fbench/default.bench"
|
||||
,"dist/build/hledger/hledger"
|
||||
-- ,"-v"
|
||||
] defaultMain
|
||||
-- withArgs ["--simplebench"] $ do
|
||||
-- withArgs ["--criterion"] $ do
|
||||
args <- getArgs
|
||||
if "--criterion" `elem` args
|
||||
then withArgs [] benchWithCriterion
|
||||
else if "--simplebench" `elem` args
|
||||
then benchWithSimplebench
|
||||
else benchWithTimeit
|
||||
-- hFlush stdout
|
||||
threadDelay (stackFinalOutputDelaySeconds * 1000000)
|
||||
|
||||
-- a little delay to avoid truncation of final output by stack
|
||||
-- in a slow-rendering terminal, such as an emacs shell
|
||||
threadDelay 500000
|
||||
benchWithTimeit = do
|
||||
getCurrentDirectory >>= printf "Benchmarking hledger in %s with timeit\n"
|
||||
let opts = defcliopts{output_file_=Just outputfile}
|
||||
(t0,j) <- timeit ("read "++inputfile) $ either error id <$> readJournalFile Nothing Nothing True inputfile
|
||||
(t1,_) <- timeit ("print") $ print' opts j
|
||||
(t2,_) <- timeit ("register") $ register opts j
|
||||
(t3,_) <- timeit ("balance") $ balance opts j
|
||||
(t4,_) <- timeit ("stats") $ stats opts j
|
||||
printf "Total: %0.2fs\n" (sum [t0,t1,t2,t3,t4])
|
||||
|
||||
timeit :: String -> IO a -> IO (Double, a)
|
||||
timeit name action = do
|
||||
printf "%s%s" name (replicate (40 - length name) ' ')
|
||||
(t,a) <- timeItT action
|
||||
printf "[%.2fs]\n" t
|
||||
return (t,a)
|
||||
|
||||
benchWithCriterion = do
|
||||
getCurrentDirectory >>= printf "Benchmarking hledger in %s with criterion\n"
|
||||
let opts = defcliopts{output_file_=Just "/dev/null"}
|
||||
j <- either error id <$> readJournalFile Nothing Nothing True inputfile
|
||||
Criterion.Main.defaultMainWith defaultConfig $ [
|
||||
bench ("read "++inputfile) $ nfIO $ (either error const <$> readJournalFile Nothing Nothing True inputfile),
|
||||
bench ("print") $ nfIO $ print' opts j,
|
||||
bench ("register") $ nfIO $ register opts j,
|
||||
bench ("balance") $ nfIO $ balance opts j,
|
||||
bench ("stats") $ nfIO $ stats opts j
|
||||
]
|
||||
|
||||
benchWithSimplebench = do
|
||||
let whichcmd = if os == "mingw32" then "where" else "which"
|
||||
exe <- init <$> readProcess whichcmd ["hledger"] ""
|
||||
pwd <- getCurrentDirectory
|
||||
printf "Benchmarking %s in %s with simplebench and shell\n" exe pwd
|
||||
flip withArgs SimpleBench.defaultMain [
|
||||
"-fbench/default.bench"
|
||||
,"-v"
|
||||
,"hledger"
|
||||
]
|
||||
|
||||
@ -214,8 +214,10 @@ benchmark bench
|
||||
hledger,
|
||||
base >= 4.3 && < 5,
|
||||
base-compat >= 0.8.1,
|
||||
criterion,
|
||||
html,
|
||||
tabular >= 0.2 && < 0.3,
|
||||
timeit,
|
||||
process,
|
||||
filepath,
|
||||
directory
|
||||
|
||||
@ -4,4 +4,5 @@ packages:
|
||||
- hledger-web
|
||||
flags: {}
|
||||
resolver: nightly-2015-06-17
|
||||
extra-deps: []
|
||||
extra-deps:
|
||||
- timeit-1.0.0.0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user