6import Criterion.Main (Benchmark, bench, defaultMainWith, nfIO)
7import Criterion.Config (defaultConfig, ljust, Config(cfgSamples))
10import qualified Data.Serialize as Ser
11import Data.Word (Word8)
13 ( AddrInfoFlag (AI_PASSIVE), HostName, ServiceName, Socket
14 , SocketType (Stream), SocketOption (ReuseAddr)
15 , accept, addrAddress, addrFlags, addrFamily, bindSocket, defaultProtocol
17 , getAddrInfo, listen, setSocketOption, socket, sClose, withSocketsDo )
18import System.Environment (getArgs, withArgs)
20import qualified Network.Socket as N
25import Data.ByteString (ByteString)
26import qualified Network.Socket.ByteString as NBS
30import Data.ByteString.Lazy (ByteString)
31import qualified Network.Socket.ByteString.Lazy as NBS
32encode = Ser.encodeLazy
33decode = Ser.decodeLazy
37encode :: Ser.Serialize a => a -> ByteString
38decode :: Ser.Serialize a => ByteString -> Either String a
40-- | This performs a ping benchmark on a TCP connection created by
41-- Network.Socket. To compile this file, you might use:
43-- ghc --make -idistributed-process/src -inetwork-transport/src -O2 benchmarks/PingTCP.hs
45-- To use the compiled binary, first set up the server on the current machine:
47-- ./benchmarks/PingTCP server 8080
49-- Next, perform the benchmark on a client using the server address, where
50-- each mark is 1000 pings:
52-- ./benchmarks/PingTCP client 0.0.0.0 8080 1000
54-- The server must be restarted between benchmarks.
59 "server" : service : [] -> withSocketsDo $ do
60 putStrLn "server: creating TCP connection"
61 serverAddrs <- getAddrInfo
62 (Just (defaultHints { addrFlags = [AI_PASSIVE] } ))
65 let serverAddr = head serverAddrs
66 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
67 setSocketOption sock ReuseAddr 1
68 bindSocket sock (addrAddress serverAddr)
70 putStrLn "server: awaiting client connection"
72 (clientSock, clientAddr) <- accept sock
74 putStrLn "server: listening for pings"
75 forever (pong clientSock)
77 "client": host : service : pingsStr : reps : args' -> withSocketsDo $ do
78 let pings = read pingsStr
79 serverAddrs <- getAddrInfo
83 let serverAddr = head serverAddrs
84 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
86 N.connect sock (addrAddress serverAddr)
88 -- benchmark the pings
89 case (read reps) :: Int of
90 0 -> error "What would zero reps mean?"
91 1 -> do putStrLn "Because you're timing only one trial, skipping Criterion..."
92 replicateM_ pings (ping sock)
93 n -> withArgs args' $ defaultMainWith
94 (defaultConfig{ cfgSamples = ljust n })
95 (return ()) -- Init action.
96 [ benchPing sock (fromIntegral pings) ]
97 putStrLn "Done with all ping/pongs."
99-- withArgs args' $ defaultMain [ benchPing sock pings ]
100-- replicateM_ pings (ping sock)
102-- | Each `ping` sends a single byte, and expects to receive one
104ping :: Socket -> IO Int64
106 NBS.send sock $ encode (42 :: Int64)
107 bs <- NBS.recv sock 8
108 either error return $ decode bs
110pong :: Socket -> IO ()
112 bs <- NBS.recv sock 8
116benchPing :: Socket -> Int64 -> Benchmark
119 nfIO (replicateM_ (fromIntegral n) (ping sock))
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