Skip to content

Commit

Permalink
Merge pull request #21 from velveteer/some-fixes
Browse files Browse the repository at this point in the history
Adjust vector bounds and add Decoder instances
  • Loading branch information
velveteer authored Mar 9, 2023
2 parents 6f574ae + 33ac73e commit 3780bf0
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 176 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Revision history for hermes-json

## 0.5.0.0 -- 2023-03-08

* Convert `DecoderM` callbacks to `Decoder`. This is a breaking change.
* Add useful instances for the `Decoder` monad
* Remove some redundant functions
* Adjust `vector` bounds

## 0.4.0.0 -- 2023-03-07

* Update simdjson to 3.1.3
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,17 @@ We benchmark the following operations using both `hermes-json` and `aeson` stric
<!-- AUTO-GENERATED-CONTENT:START (BENCHES) -->
| Name | Mean (ps) | 2*Stdev (ps) | Allocated | Copied | Peak Memory |
| --------------------------------------- | ------------- | ------------ | ---------- | ---------- | ----------- |
| All.Decode.Arrays.Hermes | 267104550000 | 18274712758 | 503599934 | 439150544 | 541065216 |
| All.Decode.Arrays.Aeson | 2205838200000 | 108871466542 | 7094759154 | 2392723275 | 1166016512 |
| All.Decode.Persons.Hermes | 47153700000 | 3880584170 | 144901928 | 57032737 | 1166016512 |
| All.Decode.Persons.Aeson | 134265700000 | 7195219536 | 357269946 | 188529734 | 1166016512 |
| All.Decode.Partial Twitter.Hermes | 246448046 | 20934312 | 348540 | 3088 | 1166016512 |
| All.Decode.Partial Twitter.JsonStream | 2105484765 | 73210262 | 15261108 | 273820 | 1166016512 |
| All.Decode.Partial Twitter.Aeson | 4297434375 | 139205712 | 12547656 | 4625157 | 1166016512 |
| All.Decode.Persons (Aeson Value).Hermes | 108099550000 | 9966602188 | 303649194 | 138051155 | 1166016512 |
| All.Decode.Persons (Aeson Value).Aeson | 119240200000 | 9148201308 | 286148916 | 177027844 | 1166016512 |
| All.Decode.Twitter (Aeson Value).Hermes | 4261312500 | 149205128 | 12555922 | 4151184 | 1166016512 |
| All.Decode.Twitter (Aeson Value).Aeson | 4832229687 | 242990712 | 12539421 | 5527422 | 1166016512 |
| All.Decode.Arrays.Hermes | 267914650000 | 10610366160 | 503599934 | 439150544 | 541065216 |
| All.Decode.Arrays.Aeson | 2214928800000 | 160279563772 | 7094759111 | 2392723388 | 1166016512 |
| All.Decode.Persons.Hermes | 47338175000 | 4290343628 | 144901928 | 57032737 | 1166016512 |
| All.Decode.Persons.Aeson | 132864400000 | 9509102680 | 357269946 | 188529742 | 1166016512 |
| All.Decode.Partial Twitter.Hermes | 241083593 | 13856196 | 348540 | 3088 | 1166016512 |
| All.Decode.Partial Twitter.JsonStream | 2116192187 | 158907568 | 15259526 | 273821 | 1166016512 |
| All.Decode.Partial Twitter.Aeson | 4254060937 | 262619196 | 12538003 | 4634594 | 1166016512 |
| All.Decode.Persons (Aeson Value).Hermes | 106420425000 | 3747538126 | 303886293 | 135388183 | 1166016512 |
| All.Decode.Persons (Aeson Value).Aeson | 119489550000 | 9713032080 | 286148916 | 177027852 | 1166016512 |
| All.Decode.Twitter (Aeson Value).Hermes | 4164246875 | 240020934 | 12368752 | 4149211 | 1166016512 |
| All.Decode.Twitter (Aeson Value).Aeson | 4810817187 | 345165042 | 12539421 | 5527424 | 1166016512 |
| |
<!-- AUTO-GENERATED-CONTENT:END (BENCHES) -->

Expand Down
6 changes: 3 additions & 3 deletions hermes-aeson/hermes-aeson.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ library
exposed-modules:
Data.Hermes.Aeson
build-depends:
aeson ^>= 2.1.2.1,
base ^>= 4.16.4.0,
aeson >= 2.0.1 && < 2.2,
base >= 4.16.4.0,
hermes-json
hs-source-dirs: src
ghc-options: -Wall -O2
Expand All @@ -26,7 +26,7 @@ test-suite test
main-is: test.hs
ghc-options: -Wall
build-depends:
aeson >= 2.0.1 && < 2.2,
aeson,
base,
bytestring,
hermes-aeson,
Expand Down
15 changes: 8 additions & 7 deletions hermes-aeson/src/Data/Hermes/Aeson.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import qualified Data.Aeson.Key as K
import qualified Data.Aeson.KeyMap as KM

hValueToAeson :: H.Decoder A.Value
hValueToAeson = H.withType $ \ty ->
hValueToAeson = do
ty <- H.getType
case ty of
H.VArray -> H.withVector hValueToAeson (pure . A.Array)
H.VObject -> H.withObjectAsMap (pure . K.fromText) hValueToAeson (pure . A.Object . KM.fromMap)
H.VNumber -> H.withScientific (pure . A.Number)
H.VString -> H.withText (pure . A.String)
H.VBoolean -> H.withBool (pure . A.Bool)
H.VNull -> H.withNull (\isNil -> if isNil then pure A.Null else fail "expected null")
H.VArray -> A.Array <$> H.vector hValueToAeson
H.VObject -> A.Object . KM.fromMap <$> H.objectAsMap (pure . K.fromText) hValueToAeson
H.VNumber -> A.Number <$> H.scientific
H.VString -> A.String <$> H.text
H.VBoolean -> A.Bool <$> H.bool
H.VNull -> pure A.Null
22 changes: 11 additions & 11 deletions hermes-bench/bench.csv
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Name,Mean (ps),2*Stdev (ps),Allocated,Copied,Peak Memory
All.Decode.Arrays.Hermes,267104550000,18274712758,503599934,439150544,541065216
All.Decode.Arrays.Aeson,2205838200000,108871466542,7094759154,2392723275,1166016512
All.Decode.Persons.Hermes,47153700000,3880584170,144901928,57032737,1166016512
All.Decode.Persons.Aeson,134265700000,7195219536,357269946,188529734,1166016512
All.Decode.Partial Twitter.Hermes,246448046,20934312,348540,3088,1166016512
All.Decode.Partial Twitter.JsonStream,2105484765,73210262,15261108,273820,1166016512
All.Decode.Partial Twitter.Aeson,4297434375,139205712,12547656,4625157,1166016512
All.Decode.Persons (Aeson Value).Hermes,108099550000,9966602188,303649194,138051155,1166016512
All.Decode.Persons (Aeson Value).Aeson,119240200000,9148201308,286148916,177027844,1166016512
All.Decode.Twitter (Aeson Value).Hermes,4261312500,149205128,12555922,4151184,1166016512
All.Decode.Twitter (Aeson Value).Aeson,4832229687,242990712,12539421,5527422,1166016512
All.Decode.Arrays.Hermes,267914650000,10610366160,503599934,439150544,541065216
All.Decode.Arrays.Aeson,2214928800000,160279563772,7094759111,2392723388,1166016512
All.Decode.Persons.Hermes,47338175000,4290343628,144901928,57032737,1166016512
All.Decode.Persons.Aeson,132864400000,9509102680,357269946,188529742,1166016512
All.Decode.Partial Twitter.Hermes,241083593,13856196,348540,3088,1166016512
All.Decode.Partial Twitter.JsonStream,2116192187,158907568,15259526,273821,1166016512
All.Decode.Partial Twitter.Aeson,4254060937,262619196,12538003,4634594,1166016512
All.Decode.Persons (Aeson Value).Hermes,106420425000,3747538126,303886293,135388183,1166016512
All.Decode.Persons (Aeson Value).Aeson,119489550000,9713032080,286148916,177027852,1166016512
All.Decode.Twitter (Aeson Value).Hermes,4164246875,240020934,12368752,4149211,1166016512
All.Decode.Twitter (Aeson Value).Aeson,4810817187,345165042,12539421,5527424,1166016512
128 changes: 64 additions & 64 deletions hermes-bench/bench.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions hermes-json.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 3.0
name: hermes-json
version: 0.4.0.0
version: 0.5.0.0
category: Text, Web, JSON, FFI
synopsis: Fast JSON decoding via simdjson C++ bindings
description:
Expand Down Expand Up @@ -72,7 +72,7 @@ library
transformers >= 0.5.6 && < 0.6,
time >= 1.9.3 && < 1.13,
time-compat >= 1.9.5 && < 1.10,
vector >= 0.13.0 && < 0.14
vector >= 0.12.3.1 && < 0.14

hs-source-dirs: src
default-language: Haskell2010
Expand Down
2 changes: 0 additions & 2 deletions src/Data/Hermes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,12 @@ module Data.Hermes
, withBool
, withDouble
, withInt
, withNull
, withObject
, withObjectAsMap
, withScientific
, withString
, withText
, withType
, withTypeM
, withVector
-- * Raw ByteString access
, withRawByteString
Expand Down
30 changes: 30 additions & 0 deletions src/Data/Hermes/Decoder/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,34 @@ instance NFData Path

newtype Decoder a = Decoder { runDecoder :: Value -> DecoderM a }

instance Functor Decoder where
{-# INLINE fmap #-}
fmap f d = Decoder $ \val -> f <$> runDecoder d val

instance Applicative Decoder where
{-# INLINE pure #-}
pure a = Decoder $ \_ -> pure a
{-# INLINE (<*>) #-}
(Decoder f) <*> (Decoder e) = Decoder $ \val -> f val <*> e val

instance Monad Decoder where
{-# INLINE return #-}
return = pure
{-# INLINE (>>=) #-}
(Decoder d) >>= f = Decoder $ \val -> do
x <- d val
runDecoder (f x) val

instance Alternative Decoder where
{-# INLINE (<|>) #-}
(Decoder a) <|> (Decoder b) = Decoder $ \val -> a val <|> b val
{-# INLINE empty #-}
empty = Decoder $ const empty

instance MonadFail Decoder where
{-# INLINE fail #-}
fail e = Decoder $ \_ -> fail e

-- | Decode a strict `ByteString` using the simdjson::ondemand bindings.
-- Creates simdjson instances on each decode.
decodeEither :: Decoder a -> BS.ByteString -> Either HermesException a
Expand Down Expand Up @@ -139,6 +167,8 @@ parseByteStringIO hEnv d bs =
-- It is preferable to use `withHermesEnv` to keep foreign references in scope.
-- Be careful using this, the foreign references can be finalized if the
-- `HermesEnv` goes out of scope.
--
-- Do _not_ share a `HermesEnv` across multiple threads. Each thread should get its own.
mkHermesEnv :: Maybe Int -> IO HermesEnv
mkHermesEnv mCapacity = do
parser <- mkSIMDParser mCapacity
Expand Down
Loading

0 comments on commit 3780bf0

Please sign in to comment.