@@ -12,6 +12,7 @@
12import Criterion.Main
12import Criterion.Main
13import Data.ByteString (ByteString)
13import Data.ByteString (ByteString)
14import Data.Int (Int64)
14import Data.Int (Int64)
15+import Data.Maybe (fromMaybe)
16import qualified Data.ByteString as S
17import qualified Data.ByteString as S
17import qualified Data.ByteString.Char8 as B
18import qualified Data.ByteString.Char8 as B
@@ -19,6 +20,10 @@ import qualified Data.Char as C
19import qualified Numeric as N
20import qualified Numeric as N
20import qualified Test.QuickCheck as QC
21import qualified Test.QuickCheck as QC
23+-- ReadInt is a module internal to Warp.
24+import qualified ReadInt as RI
22import GHC.Prim
27import GHC.Prim
23import GHC.Types
28import GHC.Types
@@ -38,6 +43,12 @@ readDec s =
38 (x, _):_ -> x
43 (x, _):_ -> x
46+-- Use ByteString's readInteger function (which requires some extra stuff to
48+readIntegerBS :: ByteString -> Integer
49+readIntegerBS bs = fst $ fromMaybe (0, "") $ B.readInteger bs
41-- No checking for non-digits. Will overflow at 2^31 on 32 bit CPUs.
52-- No checking for non-digits. Will overflow at 2^31 on 32 bit CPUs.
42readIntRaw :: ByteString -> Int
53readIntRaw :: ByteString -> Int
43readIntRaw =
54readIntRaw =
@@ -102,6 +113,11 @@ mhDigitToInt (C# i) = I# (word2Int# $ indexWord8OffAddr# addr (ord# i))
102 \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
113 \\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
116+-- This is the one Warp actually uses.
117+readIntWarp :: ByteString -> Integer
118+readIntWarp s = fromIntegral $ RI.readInt64 s
105-- A QuickCheck property. Test that for a number >= 0, converting it to
121-- A QuickCheck property. Test that for a number >= 0, converting it to
106-- a string using show and then reading the value back with the function
122-- a string using show and then reading the value back with the function
107-- under test returns the original value.
123-- under test returns the original value.
@@ -121,24 +137,28 @@ runQuickCheckTests = do
121 QC.quickCheck (prop_read_show_idempotent readInteger)
137 QC.quickCheck (prop_read_show_idempotent readInteger)
122 QC.quickCheck (prop_read_show_idempotent readInt64MH)
138 QC.quickCheck (prop_read_show_idempotent readInt64MH)
123 QC.quickCheck (prop_read_show_idempotent readIntegerMH)
139 QC.quickCheck (prop_read_show_idempotent readIntegerMH)
140+ QC.quickCheck (prop_read_show_idempotent readIntWarp)
125runCriterionTests :: ByteString -> IO ()
143runCriterionTests :: ByteString -> IO ()
126runCriterionTests number =
144runCriterionTests number =
127 defaultMain
145 defaultMain
128 [ bench "readIntOrig" $ nf readIntOrig number
146 [ bench "readIntOrig" $ nf readIntOrig number
129 , bench "readDec" $ nf readDec number
147 , bench "readDec" $ nf readDec number
148+ , bench "readIntegerBS" $ nf readIntegerBS number
130 , bench "readRaw" $ nf readIntRaw number
149 , bench "readRaw" $ nf readIntRaw number
131 , bench "readInt" $ nf readInt number
150 , bench "readInt" $ nf readInt number
132 , bench "readInt64" $ nf readInt64 number
151 , bench "readInt64" $ nf readInt64 number
133 , bench "readInteger" $ nf readInteger number
152 , bench "readInteger" $ nf readInteger number
134 , bench "readInt64MH" $ nf readInt64MH number
153 , bench "readInt64MH" $ nf readInt64MH number
135 , bench "readIntegerMH" $ nf readIntegerMH number
154 , bench "readIntegerMH" $ nf readIntegerMH number
155+ , bench "readIntWarp" $ nf readIntWarp number
139main :: IO ()
158main :: IO ()
141 putStrLn "Quickcheck tests."
160 putStrLn "Quickcheck tests."
142 runQuickCheckTests
161 runQuickCheckTests
143 putStrLn "Criterion tests."
162 putStrLn "Criterion tests."
144 runCriterionTests "1234567898765432178979128361238162386182"
163 runCriterionTests "1234567898765432178979128361238162386182"