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