on master help sign in
Slightly improved performance of generically parsing sums

The BigSum/fromJSON/generic benchmarks goes from 13.6 us to 11.3 us. Thanks to Twan van Laarhoven for the idea of using Maybe for the parse result instead of using the parser directly

commit3ea27d6dc1f5c0aff3679e270cdebf44659a2bf0 authorBas van Dijk <v.dijk.bas@gmail.com> dateThu 3 Nov 2011, 19:36 (15 years ago) parentaf385c4
1 file changed+15−11
Data/Aeson/Types/Internal.hs+15−11
Data/Aeson/Types/Internal.hs+15−11
@@ -343,7 +343,7 @@ object = Object . M.fromList
343343--
344344-- * 'Data.Aeson.Generic' provides a generic @toJSON@ function that accepts any
345345-- type which is an instance of 'Data'.
346−--
346+--
347347-- * If your compiler has support for the @DeriveGeneric@ and
348348-- @DefaultSignatures@ language extensions, @toJSON@ will have a default generic
349349-- implementation.
@@ -382,7 +382,7 @@ class ToJSON a where
382382-- @{-\# LANGUAGE OverloadedStrings #-}
383383--
384384-- data Coord { x :: Double, y :: Double }
385−--
385+--
386386-- instance FromJSON Coord where
387387-- parseJSON ('Object' v) = Coord '<$>'
388388-- v '.:' \"x\" '<*>'
@@ -1057,10 +1057,17 @@ instance ( GFromProduct a, GFromProduct b
10571057 {-# INLINE gParseJSON #-}
10581058
10591059instance (GFromSum a, GFromSum b) => GFromJSON (a :+: b) where
1060− gParseJSON (Object (M.toList -> [keyVal])) = gParseSum keyVal
1060+ gParseJSON (Object (M.toList -> [keyVal@(key, _)])) =
1061+ case gParseSum keyVal of
1062+ Nothing -> notFound $ unpack key
1063+ Just p -> p
10611064 gParseJSON v = typeMismatch "sum (:+:)" v
10621065 {-# INLINE gParseJSON #-}
10631066
1067+notFound :: String -> Parser a
1068+notFound key = fail $ "The key \"" ++ key ++ "\" was not found"
1069+{-# INLINE notFound #-}
1070+
10641071--------------------------------------------------------------------------------
10651072
10661073class ConsFromJSON f where consParseJSON :: Value -> Parser (f a)
@@ -1131,22 +1138,19 @@ instance (GFromJSON a) => GFromProduct (S1 s a) where
11311138--------------------------------------------------------------------------------
11321139
11331140class GFromSum f where
1134− gParseSum :: Pair -> Parser (f a)
1141+ gParseSum :: Pair -> Maybe (Parser (f a))
11351142
11361143instance (GFromSum a, GFromSum b) => GFromSum (a :+: b) where
1137− gParseSum keyVal = (L1 <$> gParseSum keyVal) <|> (R1 <$> gParseSum keyVal)
1144+ gParseSum keyVal = (fmap L1 <$> gParseSum keyVal) <|>
1145+ (fmap R1 <$> gParseSum keyVal)
11381146 {-# INLINE gParseSum #-}
11391147
11401148instance (Constructor c, GFromJSON a, ConsFromJSON a) => GFromSum (C1 c a) where
11411149 gParseSum (key, value)
1142− | key == pack (conName (undefined :: t c a p)) = gParseJSON value
1143− | otherwise = notFound $ unpack key
1150+ | key == pack (conName (undefined :: t c a p)) = Just $ gParseJSON value
1151+ | otherwise = Nothing
11441152 {-# INLINE gParseSum #-}
11451153
1146−notFound :: String -> Parser a
1147−notFound key = fail $ "The key \"" ++ key ++ "\" was not found"
1148−{-# INLINE notFound #-}
1149−
11501154--------------------------------------------------------------------------------
11511155
11521156class IsRecord (f :: * -> *) b | f -> b