on master help sign in
Better living through GHC's constructed product return

Allocating a polymorphic tuple makes GHC unable to see that there's actually no allocation needed in the parsePicos loop.

commitf899572201f87643da58cba7093b5a2b201b1610 authorBryan O'Sullivan <bos@serpentine.com> dateSun 19 Jul 2015, 21:45 (11 years ago) parent5e34435
1 file changed+9−9
Data/Aeson/Parser/Time.hs+9−9
Data/Aeson/Parser/Time.hs+9−9
@@ -24,7 +24,7 @@ import Control.Applicative ((<$>), (<*>), (<*), (*>))
2424import Control.Monad (when, void)
2525import Data.Attoparsec.Text as A
2626import Data.Bits ((.&.))
27−import Data.Char (ord)
27+import Data.Char (isDigit, ord)
2828import Data.Fixed (Pico)
2929import Data.Int (Int64)
3030import Data.Maybe (fromMaybe)
@@ -78,6 +78,8 @@ timeOfDay = do
7878 then return (Local.TimeOfDay h m s)
7979 else fail "invalid time"
8080
81+data T = T {-# UNPACK #-} !Int {-# UNPACK #-} !Int64
82+
8183-- | Parse a count of seconds, with the integer part being two digits
8284-- long.
8385seconds :: Parser Pico
@@ -86,18 +88,16 @@ seconds = do
8688 mc <- peekChar
8789 case mc of
8890 Just '.' -> do
89− t <- anyChar *> takeWhile1 (\c -> c >= '0' && c <= '9')
91+ t <- anyChar *> takeWhile1 isDigit
9092 return $! parsePicos real t
9193 _ -> return $! fromIntegral real
9294
9395parsePicos :: Int -> T.Text -> Pico
94−parsePicos a0 t =
95− let (n,t') = T.foldl' step (12 :: Int, fromIntegral a0 :: Int64) t
96− in mkPico (fromIntegral (t' * 10^n))
97− where step na@(n,a) c
98− | n <= 0 = na
99− | otherwise = mkPair (n-1) (10 * a + fromIntegral (ord c) .&. 15)
100− mkPair !x !y = (x,y)
96+parsePicos a0 t = mkPico (fromIntegral (t' * 10^n))
97+ where T n t' = T.foldl' step (T 12 (fromIntegral a0)) t
98+ step ma@(T m a) c
99+ | m <= 0 = ma
100+ | otherwise = T (m-1) (10 * a + fromIntegral (ord c) .&. 15)
101101
102102-- | Parse a time zone, and return 'Nothing' if the offset from UTC is
103103-- zero. (This makes some speedups possible.)