on master help sign in
warp : Use MagicHash version of readInt.
commitbc9013a3c371ea607609ab1d5cae182678e8f38f authorErik de Castro Lopo <erikd@mega-nerd.com> dateTue 24 Jan 2012, 13:59 (15 years ago) parent98afc83
1 file changed+42−2
warp/Network/Wai/Handler/Warp.hs+42−2
warp/Network/Wai/Handler/Warp.hs+42−2
@@ -3,6 +3,7 @@
33{-# LANGUAGE OverloadedStrings #-}
44{-# LANGUAGE CPP #-}
55{-# LANGUAGE BangPatterns #-}
6+{-# LANGUAGE MagicHash #-}
67---------------------------------------------------------
78--
89-- Module : Network.Wai.Handler.Warp
@@ -113,6 +114,9 @@ import Control.Monad (forever, when)
113114import qualified Network.HTTP.Types as H
114115import qualified Data.CaseInsensitive as CI
115116import System.IO (hPutStrLn, stderr)
117+import Data.Int (Int64)
118+import GHC.Prim
119+import GHC.Types
116120
117121#if WINDOWS
118122import Control.Concurrent (threadDelay)
@@ -650,9 +654,45 @@ checkCR bs pos =
650654-- This function is used to parse the Content-Length field of HTTP headers and
651655-- is a performance hot spot. It should only be replaced with something
652656-- significantly and provably faster.
657+-- It needs to be able work correctly on 32 bit CPUs for file sizes > 2G so we
658+-- use Int64 here and then make a generic 'readInt' that allows conversion to
659+-- Int and Integer.
653660readInt :: Integral a => ByteString -> a
654−readInt bs = fromIntegral
655− $ B.foldl' (\i c -> i * 10 + C.digitToInt c) 0 $ B.takeWhile C.isDigit bs
661+readInt s = fromIntegral $ readInt64MH s
662+ where
663+ readInt64MH :: ByteString -> Int64
664+ readInt64MH bs =
665+ B.foldl' (\i c -> i * 10 + fromIntegral (mhDigitToInt c)) 0
666+ $ B.takeWhile C.isDigit bs
667+{-# INLINE readInt #-}
668+
669+data Table = Table !Addr#
670+
671+mhDigitToInt :: Char -> Int
672+mhDigitToInt (C# i) = I# (word2Int# $ indexWord8OffAddr# addr (ord# i))
673+ where
674+ !(Table addr) = table
675+ table :: Table
676+ table = Table
677+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
678+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
679+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
680+ \\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\x00\x00\x00\x00\x00\
681+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
682+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
683+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
684+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
685+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
686+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
687+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
688+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
689+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
690+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
691+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
692+ \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
693+
694+
695+
656696
657697-- | Call the inner function with a timeout manager.
658698withManager :: Int -- ^ timeout in microseconds