1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE ForeignFunctionInterface #-}
7{-# LANGUAGE GeneralizedNewtypeDeriving #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
9{-# LANGUAGE PatternSynonyms #-}
10{-# LANGUAGE RankNTypes #-}
11{-# LANGUAGE ScopedTypeVariables #-}
12{-# LANGUAGE TemplateHaskell #-}
13{-# LANGUAGE TupleSections #-}
14{-# LANGUAGE TypeSynonymInstances #-}
15{-# LANGUAGE ViewPatterns #-}
16{-# OPTIONS_GHC -fno-warn-orphans #-}
24import Reflex.Host.Class
26import Reflex.Plan.Reflex
29import qualified Reflex.Bench.Focused as Focused
30import Reflex.Spider.Internal (SpiderEventHandle)
32import Control.Applicative
33import Control.DeepSeq (NFData (..))
40import Control.Concurrent
41import Control.Concurrent.STM
42import Control.Exception
44import Control.Monad.Trans
51import Debug.Trace.LocationTH
53import System.Environment
61import qualified Data.Map as Map
63type MonadReflexHost' t m = (MonadReflexHost t m, MonadIORef m, MonadIORef (HostFrame t))
66setupFiring :: (MonadReflexHost t m, MonadIORef m) => Plan t (Event t a) -> m (EventHandle t a, Schedule t)
72-- Hack to avoid the NFData constraint for EventHandle which is a synonym
73newtype Ignore a = Ignore a
74instance NFData (Ignore a) where
77instance NFData (SpiderEventHandle x a) where
80instance NFData (Behavior t a) where
83instance NFData (Firing t) where
86-- Measure the running time
87benchFiring :: forall t m. (MonadReflexHost' t m, MonadSample t m) => (forall a. m a -> IO a) -> TestCase -> Int -> IO ()
88benchFiring runHost tc n = runHost $ do
89 let runIterations :: m a -> m ()
90 runIterations test = replicateM_ (10*n) $ do
92 liftIO $ evaluate result
95 (h, s) <- setupFiring p
96 runIterations $ readSchedule_ s $ readEvent' h
99 runIterations $ readSchedule_ (makeDense s) $ sample b
101waitForFinalizers :: IO ()
102waitForFinalizers = do
105 isFinalized <- newIORef False
106 mkWeakPtr x $ Just $ writeIORef isFinalized True
109 f <- readIORef isFinalized
114benchmarks :: [(String, Int -> IO ())]
115benchmarks = implGroup "spider" runSpiderHost cases
117 implGroup :: (MonadReflexHost' t m, MonadSample t m) => String -> (forall a. m a -> IO a) -> [(String, TestCase)] -> [(String, Int -> IO ())]
118 implGroup name runHost = group name . fmap (second (benchFiring runHost))
119 group name = fmap $ first ((name <> "/") <>)
120 sub n frames = group ("subscribing " ++ show (n, frames)) $ Focused.subscribing n frames
121 firing n = group ("firing " <> show n) $ Focused.firing n
122 merging n = group ("merging " <> show n) $ Focused.merging n
123 dynamics n = group ("dynamics " <> show n) $ Focused.dynamics n
136pattern RunTestCaseFlag = "--run-test-case"
138spawnBenchmark :: String -> Benchmark
139spawnBenchmark name = Benchmark name $ Benchmarkable $ \n -> do
140 self <- getExecutablePath
141 callProcess self [RunTestCaseFlag, name, show n, "+RTS", "-N1"]
143foreign import ccall unsafe "myCapabilityHasOtherRunnableThreads" myCapabilityHasOtherRunnableThreads :: IO Bool
149 RunTestCaseFlag : t -> case t of
150 [name, readMaybe -> Just count] -> do
151 case lookup name benchmarks of
152 Just testCase -> testCase count
154 fix $ \loop -> bool (return ()) (yield >> loop) =<< myCapabilityHasOtherRunnableThreads
156 _ -> $failure "--run-test-case: expected test name and iteration count to follow"
157 _ -> 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