git.iko.soy/typeable/attoparsec
on master help sign in
added IsSpace.hs benchmark (forgot it in the prev patch)
commitd2ac8a7739657f338aa22baab7027d60050b47e3 authorwren ng thornton <wren@community.haskell.org> dateSun 10 Oct 2010, 21:06 (16 years ago) parenta0dc751
1 file changed+123
benchmarks/IsSpace.hs+123
benchmarks/IsSpace.hsnew file+123
@@ -0,0 +1,123 @@
1+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}
2+{-# LANGUAGE ForeignFunctionInterface #-}
3+----------------------------------------------------------------
4+-- 2010.10.09
5+-- |
6+-- Module : IsSpace
7+-- Copyright : Copyright (c) 2010 wren ng thornton
8+-- License : BSD
9+-- Maintainer : wren@community.haskell.org
10+-- Stability : experimental
11+-- Portability : portable (FFI)
12+--
13+-- A benchmark for comparing different definitions of predicates
14+-- for detecting whitespace. As of the last run the results are:
15+--
16+-- * Data.Char.isSpace : 14.44786 us +/- 258.0377 ns
17+-- * isSpace_DataChar : 43.25154 us +/- 655.7037 ns
18+-- * isSpace_Char : 29.26598 us +/- 454.1445 ns
19+-- * isPerlSpace :
20+-- * Data.Attoparsec.Char8.isSpace : 81.87335 us +/- 1.195903 us
21+-- * isSpace_Char8 : 11.84677 us +/- 178.9795 ns
22+-- * isSpace_w8 : 11.55470 us +/- 133.7644 ns
23+----------------------------------------------------------------
24+module IsSpace (main) where
25+
26+import qualified Data.Char as C
27+import Data.Word (Word8)
28+import qualified Data.ByteString as B
29+import qualified Data.ByteString.Char8 as B8
30+import Foreign.C.Types (CInt)
31+
32+import Criterion (bench, nf)
33+import Criterion.Main (defaultMain)
34+
35+----------------------------------------------------------------
36+----- Character predicates
37+-- N.B. \x9..\xD == "\t\n\v\f\r"
38+
39+-- | Recognize the same characters as Perl's @/\s/@ in Unicode mode.
40+-- In particular, we recognize POSIX 1003.2 @[[:space:]]@ except
41+-- @\'\v\'@, and recognize the Unicode @\'\x85\'@, @\'\x2028\'@,
42+-- @\'\x2029\'@. Notably, @\'\x85\'@ belongs to Latin-1 (but not
43+-- ASCII) and therefore does not belong to POSIX 1003.2 @[[:space:]]@
44+-- (nor non-Unicode @/\s/@).
45+isPerlSpace :: Char -> Bool
46+isPerlSpace c
47+ = (' ' == c)
48+ || ('\t' <= c && c <= '\r' && c /= '\v')
49+ || ('\x85' == c)
50+ || ('\x2028' == c)
51+ || ('\x2029' == c)
52+{-# INLINE isPerlSpace #-}
53+
54+
55+-- | 'Data.Attoparsec.Char8.isSpace', duplicated here because it's
56+-- not exported. This is the definition as of attoparsec-0.8.1.0.
57+isSpace :: Char -> Bool
58+isSpace c = c `B8.elem` spaces
59+ where
60+ spaces = B8.pack " \n\r\t\v\f"
61+ {-# NOINLINE spaces #-}
62+{-# INLINE isSpace #-}
63+
64+
65+-- | An alternate version of 'Data.Attoparsec.Char8.isSpace'.
66+isSpace_Char8 :: Char -> Bool
67+isSpace_Char8 c = (' ' == c) || ('\t' <= c && c <= '\r')
68+{-# INLINE isSpace_Char8 #-}
69+
70+
71+-- | An alternate version of 'Data.Char.isSpace'. This uses the
72+-- same trick as 'isSpace_Char8' but we include Unicode whitespaces
73+-- too, in order to have the same results as 'Data.Char.isSpace'
74+-- (whereas 'isSpace_Char8' doesn't recognize Unicode whitespace).
75+isSpace_Char :: Char -> Bool
76+isSpace_Char c
77+ = (' ' == c)
78+ || ('\t' <= c && c <= '\r')
79+ || ('\xA0' == c)
80+ || (iswspace (fromIntegral (C.ord c)) /= 0)
81+{-# INLINE isSpace_Char #-}
82+
83+foreign import ccall unsafe "u_iswspace"
84+ iswspace :: CInt -> CInt
85+
86+-- | Verbatim version of 'Data.Char.isSpace' (i.e., 'GHC.Unicode.isSpace'
87+-- as of base-4.2.0.2) in order to try to figure out why 'isSpace_Char'
88+-- is slower than 'Data.Char.isSpace'. It appears to be something
89+-- special in how the base library was compiled.
90+isSpace_DataChar :: Char -> Bool
91+isSpace_DataChar c =
92+ c == ' ' ||
93+ c == '\t' ||
94+ c == '\n' ||
95+ c == '\r' ||
96+ c == '\f' ||
97+ c == '\v' ||
98+ c == '\xa0' ||
99+ iswspace (fromIntegral (C.ord c)) /= 0
100+{-# INLINE isSpace_DataChar #-}
101+
102+
103+-- | A 'Word8' version of 'Data.Attoparsec.Char8.isSpace'.
104+isSpace_w8 :: Word8 -> Bool
105+isSpace_w8 w = (w == 32) || (9 <= w && w <= 13)
106+{-# INLINE isSpace_w8 #-}
107+
108+----------------------------------------------------------------
109+
110+main :: IO ()
111+main = defaultMain
112+ [ bench "Data.Char.isSpace" $ nf (map C.isSpace) ['\x0'..'\255']
113+ , bench "isSpace_DataChar" $ nf (map isSpace_DataChar) ['\x0'..'\255']
114+ , bench "isSpace_Char" $ nf (map isSpace_Char) ['\x0'..'\255']
115+ , bench "isPerlSpace" $ nf (map isPerlSpace) ['\x0'..'\255']
116+ , bench "Data.Attoparsec.Char8.isSpace"
117+ $ nf (map isSpace) ['\x0'..'\255']
118+ , bench "isSpace_Char8" $ nf (map isSpace_Char8) ['\x0'..'\255']
119+ , bench "isSpace_w8" $ nf (map isSpace_w8) [0..255]
120+ ]
121+
122+----------------------------------------------------------------
123+----------------------------------------------------------- fin.