on master help sign in
Speed up UTF-8 decoding by a little over 2x
0c1bc82Bryan O'Sullivan
Data/Text/Encoding.hs+34−26
@@ -90,34 +90,42 @@ decodeUtf8With onErr bs = textP (fst a) 0 (snd a)
90 where
90 where
91 a = A.run2 (A.new len >>= outer 0 0)
91 a = A.run2 (A.new len >>= outer 0 0)
92 len = B.length bs
92 len = B.length bs
93+ idx = B.unsafeIndex bs
94+ desc = "Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream"
93 outer n0 m0 arr = go n0 m0
95 outer n0 m0 arr = go n0 m0
94 where
96 where
95− go !n !m = do
97+ go !n !m =
98+ if m < len
96− let x1 = idx m
99+ then let !x1 = idx m
97− x2 = idx (m + 1)
100+ !m1 = m + 1
98− x3 = idx (m + 2)
101+ barf = case onErr desc (Just x1) of
99− x4 = idx (m + 3)
102+ Nothing -> go n m1
100− idx = B.unsafeIndex bs
103+ Just c -> do
101− case undefined of
104+ w <- unsafeWrite arr n c
102− _| m >= len -> return (arr,n)
105+ go (n+w) m1
103− | U8.validate1 x1 -> do
106+ in if U8.validate1 x1 then do
104− A.unsafeWrite arr n (fromIntegral x1)
107+ A.unsafeWrite arr n (fromIntegral x1)
105− go (n+1) (m+1)
108+ go (n+1) m1
109+ else if m1 < len then
110+ let !x2 = idx m1; !m2 = m + 2 in
106− | m+1 < len && U8.validate2 x1 x2 -> do
111+ if U8.validate2 x1 x2 then do
107− w <- unsafeWrite arr n (U8.chr2 x1 x2)
112+ w <- unsafeWrite arr n (U8.chr2 x1 x2)
108− go (n+w) (m+2)
113+ go (n+w) m2
114+ else if m2 < len then
115+ let !x3 = idx m2; !m3 = m + 3 in
109− | m+2 < len && U8.validate3 x1 x2 x3 -> do
116+ if U8.validate3 x1 x2 x3 then do
110− w <- unsafeWrite arr n (U8.chr3 x1 x2 x3)
117+ w <- unsafeWrite arr n (U8.chr3 x1 x2 x3)
111− go (n+w) (m+3)
118+ go (n+w) m3
119+ else if m3 < len then
120+ let !x4 = idx m3 in
112− | m+3 < len && U8.validate4 x1 x2 x3 x4 -> do
121+ if U8.validate4 x1 x2 x3 x4 then do
113− w <- unsafeWrite arr n (U8.chr4 x1 x2 x3 x4)
122+ w <- unsafeWrite arr n (U8.chr4 x1 x2 x3 x4)
114− go (n+w) (m+4)
123+ go (n+w) (m+4)
115− | otherwise -> case onErr desc (Just x1) of
124+ else barf
116− Nothing -> go n (m+1)
125+ else barf
117− Just c -> do
126+ else barf
118− w <- unsafeWrite arr n c
127+ else barf
119− go (n+w) (m+1)
128+ else return (arr,n)
120− desc = "Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream"
121{-# INLINE[0] decodeUtf8With #-}
129{-# INLINE[0] decodeUtf8With #-}
122
130
123-- | Decode a 'ByteString' containing UTF-8 encoded text that is known
131-- | Decode a 'ByteString' containing UTF-8 encoded text that is known