]> gitweb @ CieloNegro.org - Lucu.git/commitdiff
Slight speed improvement
authorpho <pho@cielonegro.org>
Wed, 5 Sep 2007 17:59:32 +0000 (02:59 +0900)
committerpho <pho@cielonegro.org>
Wed, 5 Sep 2007 17:59:32 +0000 (02:59 +0900)
darcs-hash:20070905175932-62b54-c94ecd66ffaa692a3e41bb6ad8e4e1a9d06f8684.gz

Lucu.cabal
Network/HTTP/Lucu/HttpVersion.hs
Network/HTTP/Lucu/Parser.hs
Network/HTTP/Lucu/RFC1123DateTime.hs
Network/HTTP/Lucu/Request.hs
Network/HTTP/Lucu/RequestReader.hs
Network/HTTP/Lucu/ResponseWriter.hs

index 8429cfae8583492cb15552091ed3cfd17a899615..93381ab2ec7466af828129942bc711fad3670d00 100644 (file)
@@ -54,7 +54,8 @@ Extra-Source-Files:
         examples/Makefile
 ghc-options: -fglasgow-exts -fwarn-missing-signatures -fwarn-unused-imports -funbox-strict-fields -O3
 
+
 --Executable: HelloWorld
 --Main-Is: HelloWorld.hs
 --Hs-Source-Dirs: ., examples
---ghc-options: -threaded -fglasgow-exts -O3
+--ghc-options: -fglasgow-exts -O3 -prof -auto-all
index e1ed0f38024fd9836629c84eee5d9bef20fd46cc..bd904e8c58b21bf5526620ffb1473d0d6f2af523 100644 (file)
@@ -32,7 +32,11 @@ httpVersionP = do string "HTTP/"
                   major <- many1 digit
                   char '.'
                   minor <- many1 digit
-                  return $ HttpVersion (read major) (read minor)
+                  return $ HttpVersion (read' major) (read' minor)
+    where
+      read' "1" = 1 -- この二つが
+      read' "0" = 0 -- 壓倒的に頻出する
+      read' s   = read s
 
 
 hPutHttpVersion :: Handle -> HttpVersion -> IO ()
index 174a28997e04b85641392ea6062662f3705ed67d..80d7707f441ace9da97882f19d1e022d45a0bded 100644 (file)
@@ -20,6 +20,8 @@ module Network.HTTP.Lucu.Parser
     ( Parser
     , ParserResult(..)
 
+    , failP
+
     , parse
     , parseStr
 
@@ -36,8 +38,6 @@ module Network.HTTP.Lucu.Parser
     , notFollowedBy
     , many
     , many1
-    , manyTill
-    , many1Till
     , count
     , option
     , sepBy
@@ -82,6 +82,10 @@ instance Monad Parser where
     return x = x `seq` Parser $! return $! Success x
     fail _   = Parser $! return $! IllegalInput
 
+-- |@'failP'@ is just a synonym for @'Prelude.fail Prelude.undefined'@.
+failP :: Parser a
+failP = fail undefined
+
 -- |@'parse' p bstr@ parses @bstr@ with @p@ and returns @(result,
 -- remaining)@.
 parse :: Parser a -> ByteString -> (ParserResult a, ByteString)
@@ -104,9 +108,8 @@ anyChar = Parser $!
              if B.null input then
                  return ReachedEOF
                else
-                 do let c = B.head input
-                    put (B.tail input, isEOFFatal)
-                    return (Success c)
+                 do put (B.tail input, isEOFFatal)
+                    return (Success $! B.head input)
 
 
 eof :: Parser ()
@@ -134,8 +137,10 @@ allowEOF f = f `seq`
 satisfy :: (Char -> Bool) -> Parser Char
 satisfy f = f `seq`
             do c <- anyChar
-               unless (f c) (fail "")
-               return c
+               if f c then
+                   return c
+                 else
+                   failP
 
 
 char :: Char -> Parser Char
@@ -169,12 +174,12 @@ f <|> g
 
 
 oneOf :: [Char] -> Parser Char
-oneOf = foldl (<|>) (fail "") . map char
+oneOf = foldl (<|>) failP . map char
 
 
 notFollowedBy :: Parser a -> Parser ()
 notFollowedBy p = p `seq`
-                  p >>= fail "" <|> return ()
+                  (p >> failP) <|> return ()
 
 
 digit :: Parser Char
@@ -182,7 +187,7 @@ digit = do c <- anyChar
            if c >= '0' && c <= '9' then
                return c
              else
-               fail ""
+               failP
 
 
 hexDigit :: Parser Char
@@ -192,7 +197,7 @@ hexDigit = do c <- anyChar
                  (c >= 'A' && c <= 'F') then
                   return c
                 else
-                  fail ""
+                  failP
 
 
 many :: Parser a -> Parser [a]
@@ -206,26 +211,9 @@ many p = p `seq`
 
 many1 :: Parser a -> Parser [a]
 many1 p = p `seq`
-          do ret <- many p
-             case ret of
-               [] -> fail ""
-               xs -> return xs
-
-
-manyTill :: Parser a -> Parser end -> Parser [a]
-manyTill p end
-    = p `seq` end `seq`
-      many $! do x <- p
-                 end
-                 return x
-
-
-many1Till :: Parser a -> Parser end -> Parser [a]
-many1Till p end
-    = p `seq` end `seq`
-      many1 $! do x <- p
-                  end
-                  return x
+          do x  <- p
+             xs <- many p
+             return (x:xs)
 
 
 count :: Int -> Parser a -> Parser [a]
index 9962c16924a935aa1e28e57bc7d72dd8f310b880..580691b7f4741a4370584f158f288af0e1adbeda 100644 (file)
@@ -70,12 +70,12 @@ parseHTTPDateTime src
 
 
 httpDateTime :: Parser ClockTime
-httpDateTime = do foldl (<|>) (fail "") (map string week)
+httpDateTime = do foldl (<|>) failP (map string week)
                   char ','
                   char ' '
                   day  <- liftM read (count 2 digit)
                   char ' '
-                  mon  <- foldl (<|>) (fail "") (map tryEqToFst (zip month [1..]))
+                  mon  <- foldl (<|>) failP (map tryEqToFst (zip month [1..]))
                   char ' '
                   year <- liftM read (count 4 digit)
                   char ' '
index b316730d1112174b26e8aec564b20dd4c38c2ea0..3fc0164ca167de1116504478e0363e6e421de1cb 100644 (file)
@@ -76,7 +76,7 @@ methodP = (let methods = [ ("OPTIONS", OPTIONS)
                          , ("TRACE"  , TRACE  )
                          , ("CONNECT", CONNECT)
                          ]
-           in foldl (<|>) (fail "") $ map (\ (str, mth)
+           in foldl (<|>) failP $ map (\ (str, mth)
                                            -> string str >> return mth) methods)
           <|>
           token >>= return . ExtensionMethod
@@ -85,5 +85,5 @@ methodP = (let methods = [ ("OPTIONS", OPTIONS)
 uriP :: Parser URI
 uriP = do str <- many1 $ satisfy (\ c -> not (isCtl c || c == ' '))
           case parseURIReference str of
-            Nothing  -> fail ""
+            Nothing  -> failP
             Just uri -> return uri
\ No newline at end of file
index d1505e80b8386e0f5e42e4b695a1fcf2e91e9a31..091a3a2f92e31735641e4bf46fc6dba7431deb39 100644 (file)
@@ -41,7 +41,8 @@ requestReader cnf tree h addr tQueue
       acceptRequest input
           -- キューに最大パイプライン深度以上のリクエストが溜まってゐる
           -- 時は、それが限度以下になるまで待つ。
-          = do atomically $ do queue    <- readTVar tQueue
+          = {-# SCC "acceptRequest" #-}
+            do atomically $ do queue    <- readTVar tQueue
                                when (S.length queue >= cnfMaxPipelineDepth cnf)
                                     retry
 
@@ -55,7 +56,8 @@ requestReader cnf tree h addr tQueue
 
       acceptNonparsableRequest :: StatusCode -> IO ()
       acceptNonparsableRequest status
-          = do itr <- newInteraction cnf addr Nothing
+          = {-# SCC "acceptNonparsableRequest" #-}
+            do itr <- newInteraction cnf addr Nothing
                atomically $ do updateItr itr itrResponse
                                              $ \ res -> res {
                                                           resStatus = status
@@ -68,7 +70,8 @@ requestReader cnf tree h addr tQueue
 
       acceptParsableRequest :: Request -> ByteString -> IO ()
       acceptParsableRequest req input
-          = do itr <- newInteraction cnf addr (Just req)
+          = {-# SCC "acceptParsableRequest" #-}
+            do itr <- newInteraction cnf addr (Just req)
                action
                    <- atomically $
                       do preprocess itr
@@ -86,7 +89,8 @@ requestReader cnf tree h addr tQueue
 
       acceptSemanticallyInvalidRequest :: Interaction -> ByteString -> STM (IO ())
       acceptSemanticallyInvalidRequest itr input
-          = do writeItr itr itrState Done
+          = {-# SCC "acceptSemanticallyInvalidRequest" #-}
+            do writeItr itr itrState Done
                writeDefaultPage itr
                postprocess itr
                enqueue itr
@@ -94,7 +98,8 @@ requestReader cnf tree h addr tQueue
 
       acceptRequestForNonexistentResource :: Interaction -> ByteString -> STM (IO ())
       acceptRequestForNonexistentResource itr input
-          = do updateItr itr itrResponse 
+          = {-# SCC "acceptRequestForNonexistentResource" #-}
+            do updateItr itr itrResponse 
                              $ \res -> res {
                                          resStatus = NotFound
                                        }
@@ -106,7 +111,8 @@ requestReader cnf tree h addr tQueue
 
       acceptRequestForExistentResource :: Interaction -> ByteString -> [String] -> ResourceDef -> STM (IO ())
       acceptRequestForExistentResource oldItr input rsrcPath rsrcDef
-          = do let itr = oldItr { itrResourcePath = Just rsrcPath }
+          = {-# SCC "acceptRequestForExistentResource" #-}
+            do let itr = oldItr { itrResourcePath = Just rsrcPath }
                requestHasBody <- readItr itr itrRequestHasBody id
                enqueue itr
                return $ do runResource rsrcDef itr
@@ -117,7 +123,8 @@ requestReader cnf tree h addr tQueue
 
       observeRequest :: Interaction -> ByteString -> IO ()
       observeRequest itr input
-          = do isChunked <- atomically $ readItr itr itrRequestIsChunked id
+          = {-# SCC "observeRequest" #-}
+            do isChunked <- atomically $ readItr itr itrRequestIsChunked id
                if isChunked then
                    observeChunkedRequest itr input
                  else
@@ -125,7 +132,8 @@ requestReader cnf tree h addr tQueue
 
       observeChunkedRequest :: Interaction -> ByteString -> IO ()
       observeChunkedRequest itr input
-          = do action
+          = {-# SCC "observeChunkedRequest" #-}
+            do action
                    <- atomically $
                       do isOver <- readItr itr itrReqChunkIsOver id
                          if isOver then
@@ -195,7 +203,8 @@ requestReader cnf tree h addr tQueue
 
       seekNextChunk :: Interaction -> ByteString -> STM (IO ())
       seekNextChunk itr input
-          = case parse chunkHeaderP input of
+          = {-# SCC "seekNextChunk" #-}
+            case parse chunkHeaderP input of
               -- 最終チャンク (中身が空)
               (Success 0, input')
                   -> case parse chunkTrailerP input' of
@@ -217,7 +226,8 @@ requestReader cnf tree h addr tQueue
 
       chunkWasMalformed :: Interaction -> IO ()
       chunkWasMalformed itr
-          = atomically $ do updateItr itr itrResponse 
+          = {-# SCC "chunkWasMalformed" #-}
+            atomically $ do updateItr itr itrResponse 
                                           $ \ res -> res {
                                                        resStatus = BadRequest
                                                      }
@@ -228,7 +238,8 @@ requestReader cnf tree h addr tQueue
 
       observeNonChunkedRequest :: Interaction -> ByteString -> IO ()
       observeNonChunkedRequest itr input
-          = do action
+          = {-# SCC "observeNonChunkedRequest" #-}
+            do action
                    <- atomically $
                       do wantedM <- readItr itr itrReqBodyWanted id
                          if wantedM == Nothing then
@@ -273,5 +284,6 @@ requestReader cnf tree h addr tQueue
                action
 
       enqueue :: Interaction -> STM ()
-      enqueue itr = do queue <- readTVar tQueue
+      enqueue itr = {-# SCC "enqueue" #-}
+                    do queue <- readTVar tQueue
                        writeTVar tQueue (itr <| queue)
\ No newline at end of file
index a3a6af106071d6d8a5f7b357fab3ee4823e057ef..be9f37088143ebc3e92eb73771b9dd3c1733df92 100644 (file)
@@ -32,7 +32,8 @@ responseWriter cnf h tQueue readerTID
     where
       awaitSomethingToWrite :: IO ()
       awaitSomethingToWrite 
-          = do action
+          = {-# SCC "awaitSomethingToWrite" #-}
+            do action
                    <- atomically $!
                       do -- キューが空でなくなるまで待つ
                          queue <- readTVar tQueue
@@ -56,7 +57,8 @@ responseWriter cnf h tQueue readerTID
 
       writeContinueIfNecessary :: Interaction -> STM (IO ())
       writeContinueIfNecessary itr
-          = itr `seq`
+          = {-# SCC "writeContinueIfNecessary" #-}
+            itr `seq`
             do expectedContinue <- readItr itr itrExpectedContinue id
                if expectedContinue then
                    do wroteContinue <- readItr itr itrWroteContinue id
@@ -78,11 +80,12 @@ responseWriter cnf h tQueue readerTID
           -- れば、ヘッダを出力する。ヘッダ出力後であり、bodyToSend が
           -- 空でなければ、それを出力する。空である時は、もし状態が
           -- Done であれば後処理をする。
-          = itr `seq`
+          = {-# SCC "writeHeaderOrBodyIfNecessary" #-}
+            itr `seq`
             do wroteHeader <- readItr itr itrWroteHeader id
                
                if not wroteHeader then
-                   return $ writeHeader itr
+                   return $! writeHeader itr
                  else
                    do bodyToSend <- readItr itr itrBodyToSend id
 
@@ -98,7 +101,8 @@ responseWriter cnf h tQueue readerTID
 
       writeContinue :: Interaction -> IO ()
       writeContinue itr
-          = itr `seq`
+          = {-# SCC "writeContinue" #-}
+            itr `seq`
             do let cont = Response {
                             resVersion = HttpVersion 1 1
                           , resStatus  = Continue
@@ -112,7 +116,8 @@ responseWriter cnf h tQueue readerTID
 
       writeHeader :: Interaction -> IO ()
       writeHeader itr
-          = itr `seq`
+          = {-# SCC "writeHeader" #-}
+            itr `seq`
             do res <- atomically $! do writeItr itr itrWroteHeader True
                                        readItr itr itrResponse id
                hPutResponse h res
@@ -121,7 +126,8 @@ responseWriter cnf h tQueue readerTID
       
       writeBodyChunk :: Interaction -> IO ()
       writeBodyChunk itr
-          = itr `seq`
+          = {-# SCC "writeBodyChunk" #-}
+            itr `seq`
             do willDiscardBody <- atomically $! readItr itr itrWillDiscardBody id
                willChunkBody   <- atomically $! readItr itr itrWillChunkBody   id
                chunk           <- atomically $! do chunk <- readItr itr itrBodyToSend id
@@ -140,7 +146,8 @@ responseWriter cnf h tQueue readerTID
 
       finishBodyChunk :: Interaction -> IO ()
       finishBodyChunk itr
-          = itr `seq`
+          = {-# SCC "finishBodyChunk" #-}
+            itr `seq`
             do willDiscardBody <- atomically $! readItr itr itrWillDiscardBody id
                willChunkBody   <- atomically $! readItr itr itrWillChunkBody   id
                when (not willDiscardBody && willChunkBody)
@@ -148,7 +155,8 @@ responseWriter cnf h tQueue readerTID
 
       finalize :: Interaction -> IO ()
       finalize itr
-          = itr `seq`
+          = {-# SCC "finalize" #-}
+            itr `seq`
             do finishBodyChunk itr
                willClose <- atomically $!
                             do queue <- readTVar tQueue