{-# LANGUAGE OverloadedStrings #-}
module Main
( main
) where
import Prelude
import Control.Concurrent.Async
import Control.Monad (replicateM_)
import Criterion.Main
import Data.Char (intToDigit)
import Data.IORef
import Data.Time.Clock.POSIX
import Network.AWS.XRayClient
import System.Random
main :: IO ()
main = do
stdGenIORef <- newIORef =<< newStdGen
let
segmentIdNotShared = splitActionAcrossThreads
(pure ())
(const $ getStdRandom generateXRaySegmentId)
segmentIdShared = splitActionAcrossThreads
(newStdGen >>= newIORef)
(`withRandomGenIORef` generateXRaySegmentId)
parNewStdGen = splitActionAcrossThreads (pure ()) (const newStdGen)
defaultMain
[ bgroup
"single-threaded timings"
[ -- These ID generation functions use the machine's random number generator,
-- which can be slow if used improperly.
bench "generateTraceId" $ nfIO (generateXRayTraceId stdGenIORef)
, bench "generateSegmentId"
$ nfIO (withRandomGenIORef stdGenIORef generateXRaySegmentId)
, bench "getPOSIXTime" $ nfIO getPOSIXTime
, bench "intToDigit" $ nf intToDigit 0
, bench "newStdGen" $ whnfIO newStdGen
, bench "makeSegment" $ whnfIO (makeSegment stdGenIORef)
]
, bgroup
"generateXRaySegmentId not shared parallel"
[ benchGenerateXRaySegmentId 100 segmentIdNotShared
, benchGenerateXRaySegmentId 4 segmentIdNotShared
, benchGenerateXRaySegmentId 2 segmentIdNotShared
, benchGenerateXRaySegmentId 1 segmentIdNotShared
]
, bgroup
"generateXRaySegmentId shared parallel"
[ benchGenerateXRaySegmentId 100 segmentIdShared
, benchGenerateXRaySegmentId 4 segmentIdShared
, benchGenerateXRaySegmentId 2 segmentIdShared
, benchGenerateXRaySegmentId 1 segmentIdShared
]
, bgroup
"newStdGen parallel"
[ bench "newStdGen parallel 100" $ whnfIO $ parNewStdGen 100 10000
, bench "newStdGen parallel 4" $ whnfIO $ parNewStdGen 4 10000
, bench "newStdGen parallel 2" $ whnfIO $ parNewStdGen 2 10000
, bench "newStdGen parallel 1" $ whnfIO $ parNewStdGen 1 10000
]
]
benchGenerateXRaySegmentId :: Int -> (Int -> Int -> IO a) -> Benchmark
benchGenerateXRaySegmentId n segmentIdSharing =
bench ("generateXRaySegmentId " ++ show n) $ whnfIO $ segmentIdSharing n 10000
makeSegment :: IORef StdGen -> IO XRaySegment
makeSegment stdGenIORef = do
startTime <- getPOSIXTime
endTime <- getPOSIXTime
segmentId <- withRandomGenIORef stdGenIORef generateXRaySegmentId
pure $ xraySubsegment "segment" segmentId startTime (Just endTime)
splitActionAcrossThreads :: IO a -> (a -> IO b) -> Int -> Int -> IO ()
splitActionAcrossThreads setup action numThreads totalActions =
replicateConcurrently_ numThreads $ do
setupArg <- setup
replicateM_ (totalActions `div` numThreads) (action setupArg)