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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
{-# language BangPatterns #-}
{-# language OverloadedStrings #-}
import Criterion
import Criterion.Main
import qualified Data.Binary.Get as Get
import Network.WebSockets.Hybi13.Mask
import Data.Bits (shiftR, xor)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
setupEnv = do
let kilo = BL.replicate 1024 37
mega = BL.replicate (1024 * 1024) 37
megaU = BL.fromChunks [B.drop 1 (B.replicate (1024 * 1024) 37)]
megaS = BL.fromChunks [B.replicate (1024 * 1024) 37]
return (kilo, mega, megaU, megaS)
maskPayload' :: Maybe B.ByteString -> BL.ByteString -> BL.ByteString
maskPayload' Nothing = id
maskPayload' (Just mask) = snd . BL.mapAccumL f (cycle $ B.unpack mask)
where
f [] !c = ([], c)
f (m:ms) !c = (ms, m `xor` c)
main = defaultMain [
env setupEnv $ \ ~(kilo, mega, megaU, megaS) -> bgroup "main"
[ bgroup "kilobyte payload"
[ bgroup "zero_mask"
[ bench "current" $ nf (maskPayload (mkMask $ "\x00\x00\x00\x00")) kilo
, bench "old" $ nf (maskPayload' (Just "\x00\x00\x00\x00")) kilo
]
, bgroup "full_mask"
[ bench "current" $ nf (maskPayload (mkMask "\xFF\xFF\xFF\xFF")) kilo
, bench "current-unaligned" $ nf (maskPayload (mkMask "\xFF\xFF\xFF\xFF")) (BL.drop 1 kilo)
, bench "old" $ nf (maskPayload' (Just "\xFF\xFF\xFF\xFF")) kilo
]
, bgroup "one_byte_mask"
[ bench "current" $ nf (maskPayload (mkMask "\xCC\xCC\xCC\xCC")) kilo
, bench "old" $ nf (maskPayload' (Just "\xCC\xCC\xCC\xCC")) kilo
]
, bgroup "other_mask"
[ bench "current" $ nf (maskPayload (mkMask "\xB0\xA2\xB0\xA2")) kilo
, bench "old" $ nf (maskPayload' (Just "\xB0\xA2\xB0\xA2")) kilo
]
]
, bgroup "megabyte payload"
[ bgroup "zero_mask"
[ bench "current" $ nf (maskPayload (mkMask "\x00\x00\x00\x00")) mega
, bench "old" $ nf (maskPayload' (Just "\x00\x00\x00\x00")) mega
]
, bgroup "full_mask"
[ bench "current" $ nf (maskPayload (mkMask "\xFF\xFF\xFF\xFF")) mega
, bench "current-unaligned" $ nf (maskPayload (mkMask "\xFF\xFF\xFF\xFF")) megaU
, bench "current-aligned" $ nf (maskPayload (mkMask "\xFF\xFF\xFF\xFF")) megaS
, bench "old" $ nf (maskPayload' (Just "\xFF\xFF\xFF\xFF")) mega
]
, bgroup "one_byte_mask"
[ bench "current" $ nf (maskPayload (mkMask "\xCC\xCC\xCC\xCC")) mega
, bench "old" $ nf (maskPayload' (Just "\xCC\xCC\xCC\xCC")) mega
]
, bgroup "other_mask"
[ bench "current" $ nf (maskPayload (mkMask "\xB0\xA2\xB0\xA2")) mega
, bench "old" $ nf (maskPayload' (Just "\xB0\xA2\xB0\xA2")) mega
]
]
]
]
where
mkMask b = Just $ Get.runGet parseMask b
|