hermes-json 0.1.0.1 → 0.2.0.0
raw patch · 4 files changed
+59/−40 lines, 4 filesdep ~textPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: text
API changes (from Hackage documentation)
+ Data.Hermes.Decoder.Path: dot :: Text -> Text
+ Data.Hermes.Decoder.Path: removePath :: Text -> Decoder a -> Decoder a
+ Data.Hermes.Decoder.Path: withPath :: Text -> Decoder a -> Decoder a
+ Data.Hermes.Decoder.Path: withPathIndex :: Int -> Decoder a -> Decoder a
+ Data.Hermes.Decoder.Time: day :: Value -> Decoder Day
+ Data.Hermes.Decoder.Time: localTime :: Value -> Decoder LocalTime
+ Data.Hermes.Decoder.Time: month :: Value -> Decoder Month
+ Data.Hermes.Decoder.Time: quarter :: Value -> Decoder Quarter
+ Data.Hermes.Decoder.Time: timeOfDay :: Value -> Decoder TimeOfDay
+ Data.Hermes.Decoder.Time: timeZone :: Value -> Decoder (Maybe TimeZone)
+ Data.Hermes.Decoder.Time: utcTime :: Value -> Decoder UTCTime
+ Data.Hermes.Decoder.Time: zonedTime :: Value -> Decoder ZonedTime
+ Data.Hermes.Decoder.Types: HermesEnv :: !ForeignPtr SIMDParser -> !ForeignPtr SIMDDocument -> !Text -> HermesEnv
+ Data.Hermes.Decoder.Types: InternalException :: DocumentError -> HermesException
+ Data.Hermes.Decoder.Types: SIMDException :: DocumentError -> HermesException
+ Data.Hermes.Decoder.Types: [hDocument] :: HermesEnv -> !ForeignPtr SIMDDocument
+ Data.Hermes.Decoder.Types: [hParser] :: HermesEnv -> !ForeignPtr SIMDParser
+ Data.Hermes.Decoder.Types: [hPath] :: HermesEnv -> !Text
+ Data.Hermes.Decoder.Types: allocaArray :: (Array -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Types: allocaArrayIter :: (ArrayIter -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Types: allocaObject :: (Object -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Types: allocaObjectIter :: (ObjectIter -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Types: allocaValue :: (Value -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Types: data Decoder a
+ Data.Hermes.Decoder.Types: data DocumentError
+ Data.Hermes.Decoder.Types: data HermesEnv
+ Data.Hermes.Decoder.Types: data HermesException
+ Data.Hermes.Decoder.Types: handleErrorCode :: Text -> CInt -> Decoder ()
+ Data.Hermes.Decoder.Types: instance Control.DeepSeq.NFData Data.Hermes.Decoder.Types.DocumentError
+ Data.Hermes.Decoder.Types: instance Control.DeepSeq.NFData Data.Hermes.Decoder.Types.HermesException
+ Data.Hermes.Decoder.Types: instance Control.Monad.Fail.MonadFail Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance Control.Monad.IO.Class.MonadIO Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance Control.Monad.IO.Unlift.MonadUnliftIO Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance Control.Monad.Reader.Class.MonadReader Data.Hermes.Decoder.Types.HermesEnv Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance GHC.Base.Alternative Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance GHC.Base.Applicative Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance GHC.Base.Functor Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance GHC.Base.Monad Data.Hermes.Decoder.Types.Decoder
+ Data.Hermes.Decoder.Types: instance GHC.Classes.Eq Data.Hermes.Decoder.Types.DocumentError
+ Data.Hermes.Decoder.Types: instance GHC.Classes.Eq Data.Hermes.Decoder.Types.HermesException
+ Data.Hermes.Decoder.Types: instance GHC.Exception.Type.Exception Data.Hermes.Decoder.Types.HermesException
+ Data.Hermes.Decoder.Types: instance GHC.Generics.Generic Data.Hermes.Decoder.Types.DocumentError
+ Data.Hermes.Decoder.Types: instance GHC.Generics.Generic Data.Hermes.Decoder.Types.HermesException
+ Data.Hermes.Decoder.Types: instance GHC.Show.Show Data.Hermes.Decoder.Types.DocumentError
+ Data.Hermes.Decoder.Types: instance GHC.Show.Show Data.Hermes.Decoder.Types.HermesException
+ Data.Hermes.Decoder.Types: typePrefix :: Text -> Text
+ Data.Hermes.Decoder.Types: withDocumentPointer :: (Document -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Types: withHermesEnv :: MonadUnliftIO m => (HermesEnv -> m a) -> m a
+ Data.Hermes.Decoder.Types: withParserPointer :: (Parser -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Value: atKey :: Text -> (Value -> Decoder a) -> Object -> Decoder a
+ Data.Hermes.Decoder.Value: atKeyOptional :: Text -> (Value -> Decoder a) -> Object -> Decoder (Maybe a)
+ Data.Hermes.Decoder.Value: atKeyStrict :: Text -> (Value -> Decoder a) -> Object -> Decoder a
+ Data.Hermes.Decoder.Value: atPointer :: Text -> (Value -> Decoder a) -> Decoder a
+ Data.Hermes.Decoder.Value: bool :: Value -> Decoder Bool
+ Data.Hermes.Decoder.Value: char :: Value -> Decoder Char
+ Data.Hermes.Decoder.Value: double :: Value -> Decoder Double
+ Data.Hermes.Decoder.Value: int :: Value -> Decoder Int
+ Data.Hermes.Decoder.Value: isNull :: Value -> Decoder Bool
+ Data.Hermes.Decoder.Value: list :: (Value -> Decoder a) -> Value -> Decoder [a]
+ Data.Hermes.Decoder.Value: listOfDouble :: Value -> Decoder [Double]
+ Data.Hermes.Decoder.Value: listOfInt :: Value -> Decoder [Int]
+ Data.Hermes.Decoder.Value: nullable :: (Value -> Decoder a) -> Value -> Decoder (Maybe a)
+ Data.Hermes.Decoder.Value: objectAsKeyValues :: (Text -> Decoder k) -> (Value -> Decoder v) -> Value -> Decoder [(k, v)]
+ Data.Hermes.Decoder.Value: scientific :: Value -> Decoder Scientific
+ Data.Hermes.Decoder.Value: string :: Value -> Decoder String
+ Data.Hermes.Decoder.Value: text :: Value -> Decoder Text
+ Data.Hermes.Decoder.Value: withArray :: (Array -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withBool :: (Bool -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withDocumentValue :: (Value -> Decoder a) -> InputBuffer -> Decoder a
+ Data.Hermes.Decoder.Value: withDouble :: (Double -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withInt :: (Int -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withObject :: (Object -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withRawByteString :: (ByteString -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withString :: (String -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.Decoder.Value: withText :: (Text -> Decoder a) -> Value -> Decoder a
+ Data.Hermes.SIMDJSON.Bindings: arrayIterGetCurrentImpl :: ArrayIter -> Value -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: arrayIterIsDoneImpl :: ArrayIter -> IO CBool
+ Data.Hermes.SIMDJSON.Bindings: arrayIterMoveNextImpl :: ArrayIter -> IO ()
+ Data.Hermes.SIMDJSON.Bindings: atPointerImpl :: CString -> Int -> Document -> Value -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: currentLocationImpl :: Document -> Ptr CString -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: deleteDocumentImpl :: FunPtr (Ptr SIMDDocument -> IO ())
+ Data.Hermes.SIMDJSON.Bindings: deleteInputImpl :: FunPtr (Ptr PaddedString -> IO ())
+ Data.Hermes.SIMDJSON.Bindings: doubleArrayImpl :: Array -> Ptr Double -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: findFieldImpl :: Object -> CString -> Int -> Value -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: findFieldUnorderedImpl :: Object -> CString -> Int -> Value -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getArrayFromValueImpl :: Value -> Array -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getArrayIterFromValueImpl :: Value -> ArrayIter -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getArrayLenFromValueImpl :: Value -> Array -> Ptr CSize -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getBoolImpl :: Value -> Ptr CBool -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getDocumentValueImpl :: Parser -> InputBuffer -> Document -> Value -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getDoubleImpl :: Value -> Ptr Double -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getErrorMessageImpl :: CInt -> IO CString
+ Data.Hermes.SIMDJSON.Bindings: getIntImpl :: Value -> Ptr Int -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getObjectFromValueImpl :: Value -> Object -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getObjectIterFromValueImpl :: Value -> ObjectIter -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: getRawJSONTokenImpl :: Value -> Ptr CString -> Ptr CSize -> IO ()
+ Data.Hermes.SIMDJSON.Bindings: getStringImpl :: Value -> Ptr CString -> Ptr CSize -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: intArrayImpl :: Array -> Ptr Int -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: isNullImpl :: Value -> IO CBool
+ Data.Hermes.SIMDJSON.Bindings: makeDocumentImpl :: IO (Ptr SIMDDocument)
+ Data.Hermes.SIMDJSON.Bindings: makeInputImpl :: CString -> CSize -> IO (Ptr PaddedString)
+ Data.Hermes.SIMDJSON.Bindings: objectIterGetCurrentImpl :: ObjectIter -> Ptr CString -> Ptr CSize -> Value -> IO CInt
+ Data.Hermes.SIMDJSON.Bindings: objectIterIsDoneImpl :: ObjectIter -> IO CBool
+ Data.Hermes.SIMDJSON.Bindings: objectIterMoveNextImpl :: ObjectIter -> IO ()
+ Data.Hermes.SIMDJSON.Bindings: parserDestroy :: FunPtr (Ptr SIMDParser -> IO ())
+ Data.Hermes.SIMDJSON.Bindings: parserInit :: CSize -> IO (Ptr SIMDParser)
+ Data.Hermes.SIMDJSON.Bindings: toDebugStringImpl :: Document -> CString -> Ptr CSize -> IO ()
+ Data.Hermes.SIMDJSON.Types: Array :: Ptr JSONArray -> Array
+ Data.Hermes.SIMDJSON.Types: ArrayIter :: Ptr JSONArrayIter -> ArrayIter
+ Data.Hermes.SIMDJSON.Types: CAPACITY :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: DEPTH_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: Document :: Ptr SIMDDocument -> Document
+ Data.Hermes.SIMDJSON.Types: EMPTY :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: F_ATOM_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: INCOMPLETE_ARRAY_OR_OBJECT :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: INCORRECT_TYPE :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: INDEX_OUT_OF_BOUNDS :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: INSUFFICIENT_PADDING :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: INVALID_JSON_POINTER :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: INVALID_URI_FRAGMENT :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: IO_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: InputBuffer :: Ptr PaddedString -> InputBuffer
+ Data.Hermes.SIMDJSON.Types: MEMALLOC :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: NO_SUCH_FIELD :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: NUMBER_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: NUMBER_OUT_OF_RANGE :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: NUM_ERROR_CODES :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: N_ATOM_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: OUT_OF_BOUNDS :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: OUT_OF_ORDER_ITERATION :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: Object :: Ptr JSONObject -> Object
+ Data.Hermes.SIMDJSON.Types: ObjectIter :: Ptr JSONObjectIter -> ObjectIter
+ Data.Hermes.SIMDJSON.Types: PARSER_IN_USE :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: Parser :: Ptr SIMDParser -> Parser
+ Data.Hermes.SIMDJSON.Types: SCALAR_DOCUMENT_AS_VALUE :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: STRING_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: SUCCESS :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: TAPE_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: T_ATOM_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: UNCLOSED_STRING :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: UNESCAPED_CHARS :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: UNEXPECTED_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: UNINITIALIZED :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: UNSUPPORTED_ARCHITECTURE :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: UTF8_ERROR :: SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: Value :: Ptr JSONValue -> Value
+ Data.Hermes.SIMDJSON.Types: data JSONArray
+ Data.Hermes.SIMDJSON.Types: data JSONArrayIter
+ Data.Hermes.SIMDJSON.Types: data JSONObject
+ Data.Hermes.SIMDJSON.Types: data JSONObjectIter
+ Data.Hermes.SIMDJSON.Types: data JSONValue
+ Data.Hermes.SIMDJSON.Types: data PaddedString
+ Data.Hermes.SIMDJSON.Types: data SIMDDocument
+ Data.Hermes.SIMDJSON.Types: data SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: data SIMDParser
+ Data.Hermes.SIMDJSON.Types: instance GHC.Classes.Eq Data.Hermes.SIMDJSON.Types.SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: instance GHC.Enum.Bounded Data.Hermes.SIMDJSON.Types.SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: instance GHC.Enum.Enum Data.Hermes.SIMDJSON.Types.SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: instance GHC.Show.Show Data.Hermes.SIMDJSON.Types.SIMDErrorCode
+ Data.Hermes.SIMDJSON.Types: newtype Array
+ Data.Hermes.SIMDJSON.Types: newtype ArrayIter
+ Data.Hermes.SIMDJSON.Types: newtype Document
+ Data.Hermes.SIMDJSON.Types: newtype InputBuffer
+ Data.Hermes.SIMDJSON.Types: newtype Object
+ Data.Hermes.SIMDJSON.Types: newtype ObjectIter
+ Data.Hermes.SIMDJSON.Types: newtype Parser
+ Data.Hermes.SIMDJSON.Types: newtype Value
+ Data.Hermes.SIMDJSON.Wrapper: getDocumentInfo :: Document -> IO (Text, Text)
+ Data.Hermes.SIMDJSON.Wrapper: mkSIMDDocument :: IO (ForeignPtr SIMDDocument)
+ Data.Hermes.SIMDJSON.Wrapper: mkSIMDPaddedStr :: ByteString -> IO (ForeignPtr PaddedString)
+ Data.Hermes.SIMDJSON.Wrapper: mkSIMDParser :: Maybe Int -> IO (ForeignPtr SIMDParser)
+ Data.Hermes.SIMDJSON.Wrapper: withInputBuffer :: ByteString -> (InputBuffer -> IO a) -> IO a
Files
- CHANGELOG.md +4/−0
- README.md +42/−37
- hermes-json.cabal +2/−3
- src/Data/Hermes/Decoder/Value.hs +11/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for hermes-json +## 0.2.0.0 -- 2022-02-22++* Add support for `text` 2.0+ ## 0.1.0.1 -- 2022-01-18 * Make `-march=native` opt-in
README.md view
@@ -1,13 +1,13 @@-<p align="center">-<img src="https://raw.githubusercontent.com/velveteer/hermes/master/wings.svg" height=60 width=100 />-</p>-<h1 align="center">hermes</h1>-<p align="center">+<h1 align="left">+<img src="https://raw.githubusercontent.com/velveteer/hermes/master/wings.svg" height=25 width=50 />+hermes+</h1>+<p align="left"> <a href="https://github.com/velveteer/hermes/actions">- <img src="https://img.shields.io/github/workflow/status/velveteer/hermes/CI?style=flat-square" alt="CI badge" />+ <img src="https://img.shields.io/github/workflow/status/velveteer/hermes/CI?style=for-the-badge" alt="CI badge" /> </a> <a href="https://hackage.haskell.org/package/hermes-json">- <img src="https://img.shields.io/hackage/v/hermes-json?style=flat-square" alt="Hackage badge" />+ <img src="https://img.shields.io/hackage/v/hermes-json?label=hackage&style=for-the-badge" alt="Hackage badge" /> </a> </p> @@ -67,27 +67,31 @@ * Full decoding of a large-ish (12 MB) JSON array of objects * Partial decoding of Twitter status objects to highlight the on-demand benefits -### Intel Core i7-7500U @2.70GHz / 2x8GB RAM @LPDDR3+### Specs +* GHC 9.2.1+* aeson-2.0.3.0 with text-2.0+* Intel Core i7-7500U @2.70GHz / 2x8GB RAM @LPDDR3+ #### Non-threaded runtime <!-- AUTO-GENERATED-CONTENT:START (BENCHES) --> | Name | Mean (ps) | 2*Stdev (ps) | Allocated | Copied | Peak Memory | | --------------------------------------------------- | ------------- | ------------ | ---------- | --------- | ----------- |-| All.1 Million 3-Arrays.Hermes [[Double]] | 515111634200 | 19332030346 | 567061009 | 555768600 | 548405248 |-| All.1 Million 3-Arrays.Aeson [[Double]] | 1879357624000 | 109849580814 | 9240070406 | 918469928 | 815792128 |-| All.Small Object to Map.Hermes Decode | 1453784 | 99664 | 4509 | 143 | 815792128 |-| All.Small Object to Map.Aeson Lazy | 2936816 | 184144 | 20403 | 1 | 815792128 |-| All.Small Object to Map.Aeson Strict | 2954601 | 167788 | 20379 | 1 | 815792128 |-| All.Full Persons Array.Ordered Keys.Hermes Decode | 106374445200 | 1634370706 | 150384445 | 77972337 | 815792128 |-| All.Full Persons Array.Ordered Keys.Aeson Lazy | 449523758200 | 41027868974 | 1212515956 | 268045285 | 815792128 |-| All.Full Persons Array.Ordered Keys.Aeson Strict | 353756693800 | 33058983332 | 1212278538 | 200617993 | 815792128 |-| All.Full Persons Array.Unordered Keys.Hermes Decode | 113706475400 | 3830951512 | 150322956 | 75438334 | 815792128 |-| All.Full Persons Array.Unordered Keys.Aeson Lazy | 439971868800 | 7835893708 | 1213065712 | 264393596 | 815792128 |-| All.Full Persons Array.Unordered Keys.Aeson Strict | 353582487600 | 34203690928 | 1212032626 | 200502732 | 815792128 |-| All.Partial Twitter.Hermes Decode | 448839050 | 22309802 | 398892 | 4643 | 815792128 |-| All.Partial Twitter.Aeson Lazy | 16644838050 | 1080972950 | 52866100 | 7541778 | 815792128 |-| All.Partial Twitter.Aeson Strict | 14025762400 | 793325836 | 53294115 | 5958334 | 815792128 |+| All.1 Million 3-Arrays.Hermes [[Double]] | 514149749400 | 23001383910 | 567060714 | 555767893 | 548405248 |+| All.1 Million 3-Arrays.Aeson [[Double]] | 1909749532600 | 105016463882 | 9240071234 | 918470102 | 815792128 |+| All.Small Object to Map.Hermes Decode | 1402062 | 89160 | 4311 | 143 | 815792128 |+| All.Small Object to Map.Aeson Lazy | 3149933 | 190718 | 20444 | 5 | 815792128 |+| All.Small Object to Map.Aeson Strict | 2960649 | 197972 | 20455 | 3 | 815792128 |+| All.Full Persons Array.Ordered Keys.Hermes Decode | 87606624200 | 882987914 | 131017990 | 61609312 | 815792128 |+| All.Full Persons Array.Ordered Keys.Aeson Lazy | 412865060000 | 37200085522 | 1040817535 | 257682836 | 815792128 |+| All.Full Persons Array.Ordered Keys.Aeson Strict | 294154477200 | 3203013536 | 1039500388 | 171613607 | 815792128 |+| All.Full Persons Array.Unordered Keys.Hermes Decode | 98984943000 | 3869859988 | 131482700 | 61507519 | 815792128 |+| All.Full Persons Array.Unordered Keys.Aeson Lazy | 416241784400 | 31016972066 | 1040900869 | 257736671 | 815792128 |+| All.Full Persons Array.Unordered Keys.Aeson Strict | 295604611200 | 13477999910 | 1040897500 | 171857398 | 815792128 |+| All.Partial Twitter.Hermes Decode | 380242857 | 21886584 | 331150 | 3106 | 815792128 |+| All.Partial Twitter.Aeson Lazy | 14210219600 | 1363261550 | 38167991 | 6912052 | 815792128 |+| All.Partial Twitter.Aeson Strict | 11107521750 | 697866752 | 38738747 | 4728197 | 815792128 | | | <!-- AUTO-GENERATED-CONTENT:END (BENCHES) --> @@ -98,20 +102,20 @@ <!-- AUTO-GENERATED-CONTENT:START (BENCHES_THREADED) --> | Name | Mean (ps) | 2*Stdev (ps) | Allocated | Copied | Peak Memory | | --------------------------------------------------- | ------------- | ------------ | ---------- | --------- | ----------- |-| All.1 Million 3-Arrays.Hermes [[Double]] | 541886019300 | 28985190366 | 567061372 | 555825639 | 547356672 |-| All.1 Million 3-Arrays.Aeson [[Double]] | 1948081269800 | 127560261526 | 9240069829 | 919131304 | 815792128 |-| All.Small Object to Map.Hermes Decode | 1443894 | 82886 | 4262 | 144 | 815792128 |-| All.Small Object to Map.Aeson Lazy | 3010568 | 205200 | 20404 | 2 | 815792128 |-| All.Small Object to Map.Aeson Strict | 3012037 | 99100 | 20405 | 2 | 815792128 |-| All.Full Persons Array.Ordered Keys.Hermes Decode | 112708023300 | 5172458580 | 150387033 | 79494634 | 815792128 |-| All.Full Persons Array.Ordered Keys.Aeson Lazy | 460293246300 | 2987469998 | 1212937927 | 264367279 | 815792128 |-| All.Full Persons Array.Ordered Keys.Aeson Strict | 360104741850 | 6231191600 | 1212295571 | 192141024 | 815792128 |-| All.Full Persons Array.Unordered Keys.Hermes Decode | 118564635400 | 8355435606 | 150325103 | 76318688 | 815792128 |-| All.Full Persons Array.Unordered Keys.Aeson Lazy | 476108313200 | 33933903066 | 1212647160 | 268222585 | 815792128 |-| All.Full Persons Array.Unordered Keys.Aeson Strict | 363291220000 | 15069371922 | 1212036871 | 190951202 | 815792128 |-| All.Partial Twitter.Hermes Decode | 465476487 | 6501684 | 402833 | 4861 | 815792128 |-| All.Partial Twitter.Aeson Lazy | 17562410575 | 370107430 | 53230448 | 7657222 | 815792128 |-| All.Partial Twitter.Aeson Strict | 14433454400 | 1426192330 | 53290220 | 6050622 | 815792128 |+| All.1 Million 3-Arrays.Hermes [[Double]] | 541920265800 | 29342742108 | 567061829 | 555826856 | 548405248 |+| All.1 Million 3-Arrays.Aeson [[Double]] | 1953230810200 | 126855715860 | 9240069761 | 919129263 | 815792128 |+| All.Small Object to Map.Hermes Decode | 1472371 | 91562 | 4311 | 143 | 815792128 |+| All.Small Object to Map.Aeson Lazy | 3096479 | 193244 | 20444 | 6 | 815792128 |+| All.Small Object to Map.Aeson Strict | 2986724 | 200024 | 20456 | 5 | 815792128 |+| All.Full Persons Array.Ordered Keys.Hermes Decode | 90311085300 | 7526254196 | 130369345 | 60862744 | 815792128 |+| All.Full Persons Array.Ordered Keys.Aeson Lazy | 422369991600 | 38053428096 | 1040823664 | 257776459 | 815792128 |+| All.Full Persons Array.Ordered Keys.Aeson Strict | 300466422000 | 3072876168 | 1039500630 | 171704298 | 815792128 |+| All.Full Persons Array.Unordered Keys.Hermes Decode | 100871024200 | 2866865436 | 131482618 | 61527776 | 815792128 |+| All.Full Persons Array.Unordered Keys.Aeson Lazy | 424049660600 | 33951808604 | 1040901105 | 258769347 | 815792128 |+| All.Full Persons Array.Unordered Keys.Aeson Strict | 303529052800 | 7155692116 | 1040895670 | 172239231 | 815792128 |+| All.Partial Twitter.Hermes Decode | 385226798 | 22763366 | 331159 | 3125 | 815792128 |+| All.Partial Twitter.Aeson Lazy | 14504587600 | 979839172 | 38168119 | 6898312 | 815792128 |+| All.Partial Twitter.Aeson Strict | 11363703650 | 798733766 | 38738875 | 4741485 | 815792128 | | | <!-- AUTO-GENERATED-CONTENT:END (BENCHES_THREADED) --> @@ -119,10 +123,11 @@ ## Performance Tips +* Use `text` >= 2.0 to benefit from its UTF-8 implementation. * Decode to `Text` instead of `String` wherever possible! * Decode to `Int` or `Double` instead of `Scientific` if you can. * Decode your object fields in order. Out of order field lookups will slightly degrade performance. If encoding with `aeson`, you can leverage `toEncoding` to enforce ordering.-* You can improve performance by holding onto your own `HermesEnv`. `decodeEither` creates and destroys the simdjson instances every time it runs, which adds a performance penalty. Beware, do _not_ share a `HermesEnv` across multiple threads.+* You can improve performance by holding onto your own `HermesEnv`. `decodeEither` creates and destroys the simdjson instances every time it runs, which adds a performance penalty. Beware, do _not_ share a `HermesEnv` across multiple threads. ## Limitations
hermes-json.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hermes-json-version: 0.1.0.1+version: 0.2.0.0 category: Text, Web, JSON, FFI synopsis: Fast JSON decoding via simdjson C++ bindings description: @@ -47,7 +47,6 @@ OverloadedStrings exposed-modules: Data.Hermes- other-modules: Data.Hermes.Decoder Data.Hermes.Decoder.Path Data.Hermes.Decoder.Time@@ -66,7 +65,7 @@ dlist >= 0.8 && < 1.1, mtl >= 2.1 && < 2.3, scientific >= 0.3.6 && < 0.4,- text >= 1.2.4 && < 1.3,+ text >= 1.2.3.0 && < 1.3 || >= 2.0 && < 2.1, transformers >= 0.5.6 && < 0.6, time >= 1.9.3 && < 1.10, time-compat >= 1.9.5 && < 1.10,
src/Data/Hermes/Decoder/Value.hs view
@@ -1,5 +1,6 @@ {-# OPTIONS_HADDOCK show-extensions #-} {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE MultiWayIf #-} module Data.Hermes.Decoder.Value@@ -44,6 +45,9 @@ import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T+#if MIN_VERSION_text(2,0,0)+import qualified Data.Text.Foreign as T+#endif import UnliftIO.Foreign ( CStringLen , alloca@@ -218,7 +222,13 @@ getText = withCStringLen "text" parseTextFromCStrLen {-# INLINE getText #-} +#if MIN_VERSION_text(2,0,0) parseTextFromCStrLen :: CStringLen -> Decoder Text+parseTextFromCStrLen (cstr, len) = liftIO $ T.fromPtr (Foreign.castPtr cstr) (fromIntegral len)+{-# INLINE parseTextFromCStrLen #-}+#else++parseTextFromCStrLen :: CStringLen -> Decoder Text parseTextFromCStrLen cstr = do bs <- liftIO $ Unsafe.unsafePackCStringLen cstr case A.parseOnly asciiTextAtto bs of@@ -236,6 +246,7 @@ Nothing -> pure $ Just txt _ -> pure Nothing {-# INLINE asciiTextAtto #-}+#endif getRawByteString :: Value -> Decoder BS.ByteString getRawByteString valPtr = withRunInIO $ \run ->