1{-# LANGUAGE ConstraintKinds, TypeSynonymInstances, BangPatterns, ScopedTypeVariables, TupleSections, GADTs, RankNTypes, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, GeneralizedNewtypeDeriving, ForeignFunctionInterface, ViewPatterns, TemplateHaskell, PatternSynonyms #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
10import Reflex.Host.Class
13import Reflex.Plan.Reflex
15import Reflex.Spider.Internal (SpiderEventHandle)
16import qualified Reflex.Bench.Focused as Focused
18import Control.Applicative
19import Control.DeepSeq (NFData (..))
28import Control.Concurrent
35import qualified GHC.Event as GHC
36import Control.Concurrent.STM
38import Control.Exception
40import System.Environment
41import Debug.Trace.LocationTH
42import Control.Monad.Trans
48import qualified Data.Map as Map
50type MonadReflexHost' t m = (MonadReflexHost t m, MonadIORef m, MonadIORef (HostFrame t))
53setupFiring :: (MonadReflexHost t m, MonadIORef m) => Plan t (Event t a) -> m (EventHandle t a, Schedule t)
59-- Hack to avoid the NFData constraint for EventHandle which is a synonym
60newtype Ignore a = Ignore a
61instance NFData (Ignore a) where
64instance NFData (SpiderEventHandle a) where
67instance NFData (Behavior t a) where
70instance NFData (Firing t) where
71 rnf !(Firing _ _) = ()
73-- Measure the running time
74benchFiring :: forall t m. (MonadReflexHost' t m, MonadSample t m) => (forall a. m a -> IO a) -> TestCase -> Int -> IO ()
75benchFiring runHost tc n = runHost $ do
76 let runIterations :: m a -> m ()
77 runIterations test = replicateM_ (10*n) $ do
79 liftIO $ evaluate result
82 (h, s) <- setupFiring p
83 runIterations $ readSchedule s $ readEvent' h
86 runIterations $ readSchedule (makeDense s) $ sample b
88waitForFinalizers :: IO ()
92 isFinalized <- newIORef False
93 mkWeakPtr x $ Just $ writeIORef isFinalized True
96 f <- readIORef isFinalized
97 if f then return () else do
101benchmarks :: [(String, Int -> IO ())]
102benchmarks = implGroup "spider" runSpiderHost cases
104 implGroup :: (MonadReflexHost' t m, MonadSample t m) => String -> (forall a. m a -> IO a) -> [(String, TestCase)] -> [(String, Int -> IO ())]
105 implGroup name runHost = group name . fmap (second (benchFiring runHost))
106 group name = fmap $ first ((name <> "/") <>)
107 sub n frames = group ("subscribing " ++ show (n, frames)) $ Focused.subscribing n frames
108 firing n = group ("firing " <> show n) $ Focused.firing n
109 merging n = group ("merging " <> show n) $ Focused.merging n
110 dynamics n = group ("dynamics " <> show n) $ Focused.dynamics n
123pattern RunTestCaseFlag = "--run-test-case"
125spawnBenchmark :: String -> Benchmark
126spawnBenchmark name = Benchmark name $ Benchmarkable $ \n -> do
127 self <- getExecutablePath
128 callProcess self [RunTestCaseFlag, name, show n, "+RTS", "-N1"]
130foreign import ccall unsafe "myCapabilityHasOtherRunnableThreads" myCapabilityHasOtherRunnableThreads :: IO Bool
136 RunTestCaseFlag : t -> case t of
137 [name, readMaybe -> Just count] -> do
138 case lookup name benchmarks of
139 Just testCase -> testCase count
141 fix $ \loop -> bool (return ()) (yield >> loop) =<< myCapabilityHasOtherRunnableThreads
143 _ -> $failure "--run-test-case: expected test name and iteration count to follow"
144 _ -> defaultMainWith (defaultConfig { timeLimit = 20, csvFile = Just "dmap-original.csv", reportFile = Just "report.html" }) $ fmap (spawnBenchmark . fst) benchmarks
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list