blob: 7b01c6817c78466316ccedae762cdd3b892bb84c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
-- | A benchmark for measuring the impact of lazy bytestring chunk size on
-- server performance.
--
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Concurrent (forkIO)
import Control.Monad (forever)
import Data.Monoid (mappend)
import Network (listenOn, PortID (PortNumber))
import Network.Socket (accept, sClose)
import Prelude hiding (putStrLn)
import System.Environment (getArgs)
import Network.Socket.ByteString (recv, send)
import Network.Socket.ByteString.Lazy (sendAll)
import qualified Data.ByteString.Char8 as SBC
import qualified Data.ByteString.Lazy as LB
-- | Generate a 128k response, with a given chunk size.
--
makeResponse :: Int -- ^ Chunk size.
-> LB.ByteString -- ^ Result.
makeResponse chunkSize =
let chunks = createChunks chunkSize totalSize
in LB.fromChunks chunks
where
-- A 64 kilobyte response.
totalSize = 128 * 1024
createChunks c s
| c < s = SBC.replicate c 'a' : createChunks c (s - c)
| otherwise = SBC.replicate s 'a' : []
main :: IO ()
main = do
args <- getArgs
let port = PortNumber $ fromIntegral $ (read $ head args :: Int)
chunkSize = read $ args !! 1
socket <- listenOn port
forever $ do
(s, _) <- accept socket
forkIO (respond chunkSize s)
where
respond chunkSize s = do
_ <- recv s 1024
_ <- send s $ "HTTP/1.1 200 OK\r\n"
`mappend` "Content-Type: text/html; charset=UTF-8\r\n"
`mappend` "\r\n"
sendAll s $ makeResponse chunkSize
sClose s
|