6import Criterion.Main (Benchmark, bench, defaultMain, nfIO, bgroup)
8import qualified Data.Serialize as Ser
9import Data.Word (Word8)
11 ( AddrInfoFlag (AI_PASSIVE), HostName, ServiceName, Socket
12 , SocketType (Stream), SocketOption (ReuseAddr)
13 , accept, addrAddress, addrFlags, addrFamily, bindSocket, defaultProtocol
15 , getAddrInfo, listen, setSocketOption, socket, sClose, withSocketsDo )
16import System.Environment (getArgs, withArgs)
18import qualified Network.Socket as N
21import Data.ByteString (ByteString)
22import qualified Data.ByteString as BS
23import qualified Network.Socket.ByteString as NBS
27import Data.ByteString.Lazy (ByteString)
28import qualified Data.ByteString.Lazy as BS
29import qualified Network.Socket.ByteString.Lazy as NBS
30encode = Ser.encodeLazy
31decode = Ser.decodeLazy
35encode :: Ser.Serialize a => a -> ByteString
36decode :: Ser.Serialize a => ByteString -> Either String a
38-- | This performs a benchmark on a TCP connection to measure how long it takes
39-- to transfer a number of bytes.
40-- To compile this file, you might use:
42-- ghc --make -idistributed-process/src -inetwork-transport/src -O2 benchmarks/SendTCP.hs
44-- To use the compiled binary, first set up the server on the current machine,
45-- such that it expects 1000 bytes:
47-- ./benchmarks/SendTCP server 8080 1000
49-- Next, perform the benchmark on a client using the server address, where
50-- each mark is 1000 bytes:
52-- ./benchmarks/SendTCP client 0.0.0.0 8080 1000
54-- The server must be restarted between benchmarks.
59 "server" : service : sizeStr : [] -> withSocketsDo $ do
60 let size = read sizeStr
61 putStrLn "server: creating TCP connection"
62 serverAddrs <- getAddrInfo
63 (Just (defaultHints { addrFlags = [AI_PASSIVE] } ))
66 let serverAddr = head serverAddrs
67 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
68 setSocketOption sock ReuseAddr 1
69 bindSocket sock (addrAddress serverAddr)
71 putStrLn "server: awaiting client connection"
73 (clientSock, clientAddr) <- accept sock
75 putStrLn "server: listening for data"
77 forever $ pong clientSock size
79 "client": host : service : sizeStr : args' -> withSocketsDo $ do
80 let size = read sizeStr
81 serverAddrs <- getAddrInfo
85 let serverAddr = head serverAddrs
86 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
88 N.connect sock (addrAddress serverAddr)
91 let bs = BS.replicate size 0
92 withArgs args' $ defaultMain [ benchSend sock bs ]
94-- | Each `ping` sends a `ByteString` and expects a byte in return.
95ping :: Socket -> ByteString -> IO Word8
98 bs' <- NBS.recv sock 1
99 either error return $ decode bs
101-- pong :: Socket -> Int64 -> IO ()
103 bs <- NBS.recv sock size
104 NBS.sendAll sock (encode (0 :: Word8))
107benchSend :: Socket -> ByteString -> Benchmark
108benchSend sock bs = bench "SendTCP" $
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