mirror of
https://github.com/facebook/Haxl.git
synced 2024-10-04 06:07:32 +03:00
e978f29f64
Summary: Pull Request resolved: https://github.com/facebook/Haxl/pull/118 * add ability to set reporting flag for benchmarking * add argument parser * add a test for using lots of labels Reviewed By: simonmar Differential Revision: D20792436 fbshipit-source-id: c87bd8e996397cb2ef229cf59927530a4dac20df
167 lines
5.2 KiB
Haskell
167 lines
5.2 KiB
Haskell
-- Copyright (c) 2014-present, Facebook, Inc.
|
|
-- All rights reserved.
|
|
--
|
|
-- This source code is distributed under the terms of a BSD license,
|
|
-- found in the LICENSE file.
|
|
|
|
-- | Benchmarking tool for core performance characteristics of the Haxl monad.
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE ApplicativeDo, RecordWildCards #-}
|
|
module MonadBench (main) where
|
|
|
|
import Control.Monad
|
|
import Data.List as List
|
|
import Data.Maybe
|
|
import Data.Time.Clock
|
|
import Options.Applicative
|
|
import System.Exit
|
|
import System.IO
|
|
import Text.Printf
|
|
|
|
import Haxl.Prelude as Haxl
|
|
import Prelude()
|
|
|
|
import Haxl.Core.Memo (newMemoWith, runMemo)
|
|
|
|
import Haxl.Core
|
|
import Haxl.Core.Util
|
|
|
|
import ExampleDataSource
|
|
|
|
newtype SimpleWrite = SimpleWrite Text deriving (Eq, Show)
|
|
|
|
testEnv :: Int -> IO (Env () SimpleWrite)
|
|
testEnv report = do
|
|
exstate <- ExampleDataSource.initGlobalState
|
|
let st = stateSet exstate stateEmpty
|
|
env <- initEnv st ()
|
|
return env { flags = (flags env) { report = report } }
|
|
|
|
type Test = (String, Int, Int -> GenHaxl () SimpleWrite ())
|
|
|
|
testName :: Test -> String
|
|
testName (t,_,_) = t
|
|
|
|
allTests :: [Test]
|
|
allTests =
|
|
-- parallel, identical queries
|
|
[ ("par1", large, \n -> Haxl.sequence_ (replicate n (listWombats 3)))
|
|
-- parallel, distinct queries
|
|
, ("par2", medium, \n ->
|
|
Haxl.sequence_ (map listWombats [1..fromIntegral n]))
|
|
-- sequential, identical queries
|
|
, ("seqr", huge, \n ->
|
|
foldr andThen (return ()) (replicate n (listWombats 3)))
|
|
-- sequential, left-associated, distinct queries
|
|
, ("seql", medium, \n -> do
|
|
_ <- foldl andThen (return []) (map listWombats [1.. fromIntegral n])
|
|
return ())
|
|
-- No memoization
|
|
, ("memo0", small, \n -> Haxl.sequence_ [unionWombats | _ <- [1..n]])
|
|
-- One put, N gets.
|
|
, ("memo1", medium_large, \n ->
|
|
Haxl.sequence_ [memo (42 :: Int) unionWombats | _ <- [1..n]])
|
|
-- N puts, N gets.
|
|
, ("memo2", small, \n ->
|
|
Haxl.sequence_ [memo (i :: Int) unionWombats | i <- [1..n]])
|
|
, ("memo3", medium_large, \n -> do
|
|
ref <- newMemoWith unionWombats
|
|
let c = runMemo ref
|
|
Haxl.sequence_ [c | _ <- [1..n]])
|
|
, ("memo4", small, \n -> do
|
|
let f = unionWombatsTo
|
|
Haxl.sequence_ [f x | x <- take n $ cycle [100, 200 .. 1000]])
|
|
, ("memo5", medium_large, \n -> do
|
|
f <- memoize1 unionWombatsTo
|
|
Haxl.sequence_ [f x | x <- take n $ cycle [100, 200 .. 1000]])
|
|
, ("memo6", small, \n -> do
|
|
let f = unionWombatsFromTo
|
|
Haxl.sequence_ [ f x y
|
|
| x <- take n $ cycle [100, 200 .. 1000]
|
|
, let y = x + 1000
|
|
])
|
|
, ("memo7", medium_large, \n -> do
|
|
f <- memoize2 unionWombatsFromTo
|
|
Haxl.sequence_ [ f x y
|
|
| x <- take n $ cycle [100, 200 .. 1000]
|
|
, let y = x + 1000
|
|
])
|
|
, ("cc1", medium_large, \n ->
|
|
Haxl.sequence_ [ cachedComputation (ListWombats 1000) unionWombats
|
|
| _ <- [1..n]
|
|
])
|
|
, ("tree", 20, \n -> void $ tree n (\_ act -> act))
|
|
, ("tree_labels", 20, \n -> void $
|
|
tree n (\n act -> withLabel (textShow n) act))
|
|
-- parallel writes
|
|
, ("write1", large, \n ->
|
|
Haxl.sequence_ (replicate n (tellWrite (SimpleWrite "haha"))))
|
|
-- sequential writes
|
|
, ("write2", huge, \n -> foldr
|
|
andThen
|
|
(return ())
|
|
(replicate n (tellWrite (SimpleWrite "haha"))))
|
|
]
|
|
where
|
|
huge = large * 10
|
|
large = medium * 10
|
|
medium_large = medium * 4
|
|
medium = 200000
|
|
small = 1000
|
|
|
|
data Options = Options
|
|
{ test :: String
|
|
, nOverride :: Maybe Int
|
|
, reportFlag :: Int
|
|
}
|
|
|
|
runTest :: Options -> Test -> IO ()
|
|
runTest Options{..} (t, nDef, act) = do
|
|
let n = fromMaybe nDef nOverride
|
|
env <- testEnv reportFlag
|
|
t0 <- getCurrentTime
|
|
runHaxl env $ act n
|
|
t1 <- getCurrentTime
|
|
printf "%12s: %10d reqs: %.2fs\n"
|
|
t n (realToFrac (t1 `diffUTCTime` t0) :: Double)
|
|
|
|
optionsParser :: Parser Options
|
|
optionsParser = do
|
|
test <- argument str (metavar "TEST")
|
|
reportFlag <- option auto (long "report" <> value 0 <> metavar "REPORT")
|
|
nOverride <- optional $ argument auto (metavar "NUM")
|
|
return Options{..}
|
|
|
|
main :: IO ()
|
|
main = do
|
|
opts@Options{..} <- execParser $ info optionsParser mempty
|
|
let tests = if test == "all"
|
|
then allTests
|
|
else filter ((==) test . testName) allTests
|
|
when
|
|
(null tests)
|
|
(do
|
|
hPutStrLn stderr $ "syntax: monadbench [all|" ++
|
|
intercalate "|" (map testName allTests) ++ "]"
|
|
exitWith (ExitFailure 1))
|
|
Control.Monad.mapM_ (runTest opts) tests
|
|
|
|
tree
|
|
:: Int
|
|
-> (Int -> GenHaxl () SimpleWrite [Id] -> GenHaxl () SimpleWrite [Id])
|
|
-> GenHaxl () SimpleWrite [Id]
|
|
tree 0 wrap = wrap 0 $ listWombats 0
|
|
tree n wrap = wrap n $ concat <$> Haxl.sequence
|
|
[ tree (n-1) wrap
|
|
, listWombats (fromIntegral n), tree (n-1) wrap
|
|
]
|
|
|
|
unionWombats :: GenHaxl () SimpleWrite [Id]
|
|
unionWombats = foldl List.union [] <$> Haxl.mapM listWombats [1..1000]
|
|
|
|
unionWombatsTo :: Id -> GenHaxl () SimpleWrite [Id]
|
|
unionWombatsTo x = foldl List.union [] <$> Haxl.mapM listWombats [1..x]
|
|
|
|
unionWombatsFromTo :: Id -> Id -> GenHaxl () SimpleWrite [Id]
|
|
unionWombatsFromTo x y = foldl List.union [] <$> Haxl.mapM listWombats [x..y]
|