css-syntax-0.1.0.2: benchmark/Benchmark.hs
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad
import Criterion.Main
import System.Directory
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Data.CSS.Syntax.Tokens
import Control.DeepSeq
-- We're benchmarking speed of processing of 1MB input.
-- So we repeat any input to fill 1MB text.
fill :: T.Text -> T.Text
fill t = T.take size $ T.replicate (size `div` T.length t + 1) t
where size = 1000000
instance NFData NumericValue where rnf x = seq x ()
instance NFData Token where rnf x = seq x ()
fileBenchmarks :: NFData b => (a -> b) -> (T.Text -> a) -> IO [Benchmark]
fileBenchmarks f preprocess = do
cwd <- getCurrentDirectory
websites <- drop 2 <$> getDirectoryContents (cwd ++ "/benchmark/fixtures")
forM websites $ \website -> do
files <- drop 2 <$> getDirectoryContents (cwd ++ "/benchmark/fixtures/" ++ website)
benchmarks <- forM files $ \file -> do
body <- T.readFile $ cwd ++ "/benchmark/fixtures/" ++ website ++ "/" ++ file
pure $ bench file $ nf f $ preprocess $ fill body
pure $ bgroup website benchmarks
main :: IO ()
main = do
tokenizeBenchmarks <- fileBenchmarks tokenize id
serializeBenchmarks <- fileBenchmarks serialize tokenize
serializeTokenizeBenchmarks <- fileBenchmarks (serialize . tokenize) id
defaultMain [
bgroup "tokenize" tokenizeBenchmarks,
bgroup "serialize" serializeBenchmarks,
bgroup "serialize/tokenize" serializeTokenizeBenchmarks,
bgroup "tokenize"
[ tBench' "whitespace" " "
, bench "comment" $ nf tokenize $ "/*" <> fill " " <> "*/"
, numBench 1000
, numBench 10000
, numBench 100000
, numBench 1000000
, tBench' "aaa.." "a"
, tBench' "esc2" "\\ab"
, tBench' "esc5" "\\abcde"
, bench "url(aaa..)" $ nf tokenize $ "url(" <> fill "a" <> ")"
, bench "url(esc2)" $ nf tokenize $ "url(" <> fill "\\ab" <> ")"
, bench "badUrl(aaa..)"$ nf tokenize $ "url((" <> fill "a" <> ")"
, bench "badUrl(esc2)" $ nf tokenize $ "url((" <> fill "\\ab" <> ")"
, tBench ";"
, tBench "||"
, tBench "a;"
, tBench "1;"
, tBench "a:1;"
, tBench "1234567890;"
, tBench "z-index:1;"
, tBench "#123456 "
, tBench "#FFFFFF "
],
bgroup "serialize"
[ sBench "aaa"
, sBench ";"
, sBench "||"
, sBench "1;"
, sBench "1234567890;"
, sBench "a:1;"
, sBench "z-index:1;"
]
]
where sBench n =
let t = tokenize $ fill $ T.pack n in
rnf t `seq` bench n $ nf serialize t
tBench n = tBench' n n
tBench' nm n = bench nm $ nf tokenize $ fill $ T.pack n
numBench n = bench ("1e" ++ show n) $
nf tokenize $ fill $ "1" <> T.replicate n "0" <> " "