1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Main where
import Control.DeepSeq
import Control.Monad
import Criterion
import Criterion.Main hiding (defaultConfig)
import qualified Data.List as L
import System.Environment
import System.IO
import Text.Printf (printf)
import Yi.Buffer
import Yi.Config (Config)
import Yi.Config.Default (defaultConfig)
import Yi.Editor
import qualified Yi.Rope as R
-- bogus instance
instance NFData Editor where
rnf !_ = ()
data EditorAction = forall a b. (NFData a, NFData b) =>
EditorAction
{ _ea_act :: b -> EditorM a
, _ea_report :: a -> IO ()
, _ea_setup :: EditorM b
, _ea_name :: String
, _ea_config :: Config
}
simpleAction :: String -> EditorM () -> EditorAction
simpleAction n act = EditorAction
{ _ea_act = \() -> act
, _ea_report = \() -> return ()
, _ea_name = n
, _ea_config = defaultConfig
, _ea_setup = return ()
}
insertN :: Int -> EditorAction
insertN !n = EditorAction
{ _ea_act = \() -> do
runLoop
, _ea_report = \yis_l ->
putStrLn $ printf "Buffer has %d characters." yis_l
, _ea_name = "insert" ++ show n
, _ea_config = defaultConfig
, _ea_setup = return ()
}
where
spin n' | n' <= 0 = R.length <$> elemsB
| otherwise = do
insertB 'X'
spin $! n' - 1
runLoop = withCurrentBuffer $ spin n
acts :: [EditorAction]
acts = [ simpleAction "split20" $ replicateM_ 20 splitE
, simpleAction "newTab20" (replicateM_ 20 newTabE)
, Main.insertN 10
, Main.insertN 100
, Main.insertN 1000
, Main.insertN 100000
, Main.insertN 1000000
]
benchEditor :: (NFData a, NFData b)
=> String -- ^ Benchmark name
-> Config -- ^ Config
-> EditorM a -- ^ Setup
-> (a -> EditorM b) -- ^ Action
-> Benchmark
benchEditor bname c setup act =
env (return $! runEditor c setup emptyEditor) $ \ ~(setupEditor, a) -> do
bench bname $ nf (\a' -> snd $ runEditor c (act a') setupEditor) a
main :: IO ()
main = getArgs >>= \case
["list_actions"] -> print $ map _ea_name acts
["run_action", action_name] -> case L.find ((action_name ==) . _ea_name) acts of
Just EditorAction{..} ->
let !(!_, b) = runEditor _ea_config (_ea_setup >>= _ea_act) emptyEditor
in do
_ea_report b
putStrLn $ _ea_name ++ " finished."
_ -> do
hPutStrLn stderr $ "No such action: " ++ action_name
hPutStrLn stderr $ "Available actions: " ++ show (map _ea_name acts)
_ -> do
let benchmarks :: [Benchmark]
benchmarks = flip map acts $ \EditorAction{..} ->
benchEditor _ea_name _ea_config _ea_setup _ea_act
defaultMain benchmarks
|