Bryan O'Sullivan avatar Bryan O'Sullivan committed 34285f2

Make integer encoding 30% faster again! Oh, and some CPP cleanups.

Comments (0)

Files changed (1)

Data/Aeson/Encode/Number.hs

 import Data.Monoid (mappend, mempty)
 import Data.Attoparsec.Number (Number(..))
 import Blaze.ByteString.Builder
-import GHC.Num (quotRemInt, quotRemInteger)
+import GHC.Num (quotRemInteger)
 import GHC.Types (Int(..))
 import qualified Text.Show.ByteString as S
 
 # endif
 #endif
 
+#ifdef INTEGER_GMP
+# define PAIR(a,b) (# a,b #)
+#else
+# define PAIR(a,b) (a,b)
+#endif
+
 fromNumber :: Number -> Builder
 fromNumber (I i) = integer i
 fromNumber (D d) = fromLazyByteString (S.show d)
 integer :: Integer -> Builder
 integer (S# i#) = int (I# i#)
 integer i
-    | i < 0     = fromWord8 45 `mappend` go (-i)
+    | i < 0     = minus `mappend` go (-i)
     | otherwise = go i
   where
     go n | n < maxInt = int (fromInteger n)
          | otherwise  = putH (splitf (maxInt * maxInt) n)
 
-    splitf :: Integer -> Integer -> [Integer]
     splitf p n
-      | p > n     = [n]
-      | otherwise = splith p (splitf (p*p) n)
+      | p > n       = [n]
+      | otherwise   = splith p (splitf (p*p) n)
 
-    splith :: Integer -> [Integer] -> [Integer]
-    splith _ [    ] = error "splith: the impossible happened."
     splith p (n:ns) = case n `quotRemInteger` p of
-#ifdef INTEGER_GMP
-      (# q, r #) ->
-#else
-      (q, r) -> 
-#endif
-              if q > 0
-                then q : r : splitb p ns
-                else r : splitb p ns
-    splitb :: Integer -> [Integer] -> [Integer]
-    splitb _ [    ] = []
+                        PAIR(q,r) | q > 0     -> q : r : splitb p ns
+                                  | otherwise -> r : splitb p ns
+    splith _ _      = error "splith: the impossible happened."
+
     splitb p (n:ns) = case n `quotRemInteger` p of
-#ifdef INTEGER_GMP
-      (# q, r #) ->
-#else
-      (q, r) ->
-#endif
-                q : r : splitb p ns
+                        PAIR(q,r) -> q : r : splitb p ns
+    splitb _ _      = []
 
 int :: Int -> Builder
 int i
-    | i < 0     = fromWord8 45 `mappend` go (-i)
+    | i < 0     = minus `mappend` go (-i)
     | otherwise = go i
   where
     go n | n < 10    = digit n
          | otherwise = go (n `rem` 10) `mappend` digit (n `quot` 10)
 
 digit :: Int -> Builder
-digit n = fromWord8 (fromIntegral n + 48)
+digit n = fromWord8 $! fromIntegral n + 48
 
 data T = T !Integer !Int
 
 
 putH :: [Integer] -> Builder
 putH (n:ns) = case n `quotRemInteger` maxInt of
-#ifdef INTEGER_GMP
-  (# q', r' #) ->
-#else
-  (q', r') ->
-#endif
-    let q = fromInteger q'
-        r = fromInteger r'
-    in if q > 0
-       then int q `mappend` pblock r `mappend` putB ns
-       else int r `mappend` putB ns
+                PAIR(x,y)
+                    | q > 0     -> int q `mappend` pblock r `mappend` putB ns
+                    | otherwise -> int r `mappend` putB ns
+                    where q = fromInteger x
+                          r = fromInteger y
 putH _ = error "putH: the impossible happened"
 
 putB :: [Integer] -> Builder
 putB (n:ns) = case n `quotRemInteger` maxInt of
-#ifdef INTEGER_GMP
-  (# q', r' #) ->
-#else
-  (q', r') ->
-#endif
-    let q = fromInteger q'
-        r = fromInteger r'
-    in pblock q `mappend` pblock r `mappend` putB ns
+                PAIR(x,y) -> pblock q `mappend` pblock r `mappend` putB ns
+                    where q = fromInteger x
+                          r = fromInteger y
 putB _ = mempty
 
 pblock :: Int -> Builder
     go !d !n
         | d == 1    = digit n
         | otherwise = go (d-1) q `mappend` digit r
-        where (q, r) = n `quotRemInt` 10
+        where q = n `quot` 10
+              r = n `rem` 10
+
+minus :: Builder
+minus = fromWord8 45
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.