diff --git a/http/attoparsec/.gitignore b/http/attoparsec/.gitignore index 8ee1bf9..0c34f41 100644 --- a/http/attoparsec/.gitignore +++ b/http/attoparsec/.gitignore @@ -1 +1,3 @@ .stack-work +dist-newstyle +tags diff --git a/http/attoparsec/src/Main.hs b/http/attoparsec/src/Main.hs index aea9cd6..f4710a9 100644 --- a/http/attoparsec/src/Main.hs +++ b/http/attoparsec/src/Main.hs @@ -1,25 +1,45 @@ {-# LANGUAGE OverloadedStrings #-} -import Criterion.Main (bench, bgroup, defaultMain, env, whnf) +import Criterion.Main (bench, defaultMain, env, whnf) import qualified Data.ByteString as B import Control.Applicative import Data.Attoparsec.ByteString as P -import Data.Attoparsec.ByteString.Char8 (char8, endOfLine, isDigit_w8) -import Data.Attoparsec.ByteString.Char8 (isEndOfLine, isHorizontalSpace) +import Data.Attoparsec.ByteString.Char8 (char8, endOfLine, isDigit_w8, isEndOfLine, isHorizontalSpace) import Data.ByteString (ByteString) import Data.Word (Word8) isToken :: Word8 -> Bool -isToken w = w <= 127 && notInClass "\0-\31()<>@,;:\\\"/[]?={} \t" w +isToken w = + w <= 127 + && w > 31 -- "\0-\31" + && ( w /= 40 -- "(" + && w /= 41 -- ")" + && w /= 60 -- "<" + && w /= 62 -- ">" + && w /= 64 -- "@" + && w /= 44 -- "," + && w /= 59 -- ";" + && w /= 58 -- ":" + && w /= 92 -- "\\" + && w /= 34 -- "\"" + && w /= 91 -- "[" + && w /= 93 -- "]" + && w /= 63 -- "?" + && w /= 61 -- "=" + && w /= 123 -- "{" + && w /= 125 -- "}" + && w /= 32 -- " " + && w /= 9 -- "\t") + ) skipSpaces :: Parser () skipSpaces = satisfy isHorizontalSpace *> skipWhile isHorizontalSpace data Request = Request { - requestMethod :: ByteString - , requestUri :: ByteString - , requestVersion :: ByteString + requestMethod :: !ByteString + , requestUri :: !ByteString + , requestVersion :: !ByteString } deriving (Eq, Ord, Show) httpVersion :: Parser ByteString @@ -31,15 +51,15 @@ requestLine = Request <$> (takeWhile1 isToken <* char8 ' ') <*> (httpVersion <* endOfLine) data Header = Header { - headerName :: ByteString - , headerValue :: [ByteString] + headerName :: !ByteString + , headerValue :: ![ByteString] } deriving (Eq, Ord, Show) messageHeader :: Parser Header messageHeader = Header <$> (P.takeWhile isToken <* char8 ':' <* skipWhile isHorizontalSpace) <*> ((:) <$> (takeTill isEndOfLine <* endOfLine) - <*> (many $ skipSpaces *> takeTill isEndOfLine <* endOfLine)) + <*> many ( skipSpaces *> takeTill isEndOfLine <* endOfLine)) request :: Parser (Request, [Header]) request = (,) <$> requestLine <*> many messageHeader <* endOfLine @@ -53,19 +73,10 @@ smallFile = "../http-requests.txt" biggerFile :: FilePath biggerFile = "../bigger.txt" -setupEnv :: IO (ByteString, ByteString) -setupEnv = do - small <- B.readFile smallFile - bigger <- B.readFile biggerFile - return (small, bigger) - main :: IO () main = defaultMain - [ - env setupEnv $ \ ~(small, bigger) -> - bgroup "IO" - [ - bench "small" $ whnf (P.parseOnly allRequests) small - , bench "bigger" $ whnf (P.parseOnly allRequests) bigger - ] + [ env (B.readFile smallFile) $ \small -> + bench "small" $ whnf (P.parseOnly allRequests) small, + env (B.readFile biggerFile) $ \big -> + bench "big" $ whnf (P.parseOnly allRequests) big ]