@@ -18,8 +18,10 @@ module Data.Text.Lazy.Builder.Int
1818
1919import Data.Int (Int8, Int16, Int32, Int64)
2020import Data.Monoid (mempty)
21+import qualified Data.ByteString.Unsafe as B
2122import Data.Text.Lazy.Builder.Functions ((<>), i2d)
2223import Data.Text.Lazy.Builder.Internal
24+import Data.Text.Lazy.Builder.Int.Digits (digits)
2325import Data.Text.Array
2426import Data.Word (Word, Word8, Word16, Word32, Word64)
2527import GHC.Base (quotInt, remInt)
@@ -99,14 +101,21 @@ positive i
99101 | otherwise = let !n = countDigits i
100102 in writeN n $ \marr off -> posDecimal marr off n i
101103
102−posDecimal :: Integral a => forall s. MArray s -> Int -> Int -> a -> ST s ()
104+posDecimal :: (Integral a) =>
105+ forall s. MArray s -> Int -> Int -> a -> ST s ()
103106{-# INLINE posDecimal #-}
104107posDecimal marr off0 ds v0 = go (off0 + ds - 1) v0
105108 where go off v
106− | v < 10 = unsafeWrite marr off (i2w v)
107− | otherwise = do
108− unsafeWrite marr off (i2w (v `rem` 10))
109− go (off-1) (v `quot` 10)
109+ | v >= 100 = do
110+ write2 off $ let u = v `rem` 100
111+ in u + u
112+ go (off - 2) (v `quot` 100)
113+ | v < 10 = unsafeWrite marr off (i2w v)
114+ | otherwise = write2 off (v + v)
115+ write2 off i = do
116+ unsafeWrite marr off $ get (i + 1)
117+ unsafeWrite marr (off - 1) $ get i
118+ get i = fromIntegral $ B.unsafeIndex digits (fromIntegral i) :: Word16
110119
111120minus, zero :: Word16
112121{-# INLINE minus #-}