Bryan O'Sullivan avatar Bryan O'Sullivan committed 7019afe

Add some SCC annotations, and try to improve performance.

Comments (0)

Files changed (1)

Data/Aeson/Encode.hs

     , encode
     ) where
 
-import Blaze.ByteString.Builder
-import Blaze.ByteString.Builder.Char.Utf8
+import Blaze.ByteString.Builder (Builder, fromByteString, toLazyByteString)
+import Blaze.Text (double, integral)
+import Data.Aeson.Types (ToJSON(..), Value(..))
 import Data.Attoparsec.Number (Number(..))
-import Data.Aeson.Types (ToJSON(..), Value(..))
 import Data.Monoid (mappend)
+import Data.Text.Encoding (encodeUtf8)
 import Numeric (showHex)
-import Blaze.Text (double, integral)
+import qualified Blaze.ByteString.Builder.Char.Utf8 as Utf8
+import qualified Blaze.ByteString.Builder.Char8 as Char8
 import qualified Data.ByteString.Lazy.Char8 as L
 import qualified Data.HashMap.Strict as H
 import qualified Data.Text as T
 
 -- | Encode a JSON value to a 'Builder'.
 fromValue :: Value -> Builder
-fromValue Null = fromByteString "null"
-fromValue (Bool b) = fromByteString $ if b then "true" else "false"
-fromValue (Number n) = fromNumber n
-fromValue (String s) = string s
+fromValue Null = {-# SCC "fromValue/Null" #-} fromByteString "null"
+fromValue (Bool b) = {-# SCC "fromValue/Bool" #-}
+                     if b then fromByteString "true"
+                     else fromByteString "false"
+fromValue (Number n) = {-# SCC "fromValue/Number" #-} fromNumber n
+fromValue (String s) = {-# SCC "fromValue/String" #-} string s
 fromValue (Array v)
-    | V.null v = fromByteString "[]"
-    | otherwise = fromChar '[' `mappend`
+    | V.null v = {-# SCC "fromValue/Array" #-} fromByteString "[]"
+    | otherwise = {-# SCC "fromValue/Array" #-}
+                  Char8.fromChar '[' `mappend`
                   fromValue (V.unsafeHead v) `mappend`
-                  V.foldr f (fromChar ']') (V.unsafeTail v)
-  where f a z = fromChar ',' `mappend` fromValue a `mappend` z
-fromValue (Object m) =
+                  V.foldr f (Char8.fromChar ']') (V.unsafeTail v)
+  where f a z = Char8.fromChar ',' `mappend` fromValue a `mappend` z
+fromValue (Object m) = {-# SCC "fromValue/Object" #-}
     case H.toList m of
-      (x:xs) -> fromChar '{' `mappend`
-                one x `mappend`
-                foldr f (fromChar '}') xs
-      _ -> fromByteString "{}"
-  where f a z     = fromChar ',' `mappend` one a `mappend` z
-        one (k,v) = string k `mappend` fromChar ':' `mappend` fromValue v
+      (x:xs) -> Char8.fromChar '{' `mappend`
+                one x `mappend` foldr f (Char8.fromChar '}') xs
+      _      -> fromByteString "{}"
+  where f a z     = Char8.fromChar ',' `mappend` one a `mappend` z
+        one (k,v) = string k `mappend` Char8.fromChar ':' `mappend` fromValue v
 
 string :: T.Text -> Builder
-string s = fromChar '"' `mappend` quote s `mappend` fromChar '"'
+string s = Char8.fromChar '"' `mappend` (quote s) `mappend` Char8.fromChar '"'
   where
     quote q = case T.uncons t of
                 Just (c,t') -> fromText h `mappend` escape c `mappend` quote t'
     escape '\r' = fromByteString "\\r"
     escape '\t' = fromByteString "\\t"
     escape c
-        | c < '\x20' = fromString $ "\\u" ++ replicate (4 - length h) '0' ++ h
-        | otherwise  = fromChar c
+        | c < '\x20' = Char8.fromString $
+                       "\\u" ++ replicate (4 - length h) '0' ++ h
+        | otherwise  = Utf8.fromChar c
         where h = showHex (fromEnum c) ""
 
+-- The version in blaze-builder is way slower.
+fromText :: T.Text -> Builder
+fromText t = fromByteString (encodeUtf8 t)
+
 fromNumber :: Number -> Builder
 fromNumber (I i) = integral i
 fromNumber (D d)
 
 -- | Efficiently serialize a JSON value as a lazy 'L.ByteString'.
 encode :: ToJSON a => a -> L.ByteString
-encode = toLazyByteString . fromValue . toJSON
+encode = {-# SCC "encode" #-} toLazyByteString . fromValue .
+         {-# SCC "toJSON" #-} toJSON
 {-# INLINE encode #-}
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.