Skip to content

Add Data.Aeson.Decoding working on token stream - #996

Merged
phadej merged 4 commits into
masterfrom
tokens
Feb 11, 2023
Merged

Add Data.Aeson.Decoding working on token stream#996
phadej merged 4 commits into
masterfrom
tokens

Conversation

@phadej

Copy link
Copy Markdown
Collaborator

There are two motivation points:

  1. it's faster
  2. it's more expressive

The first point is actually accidental, but nevertheless very nice to have. In benchmarks decoding strict bytestring through Tokens seems to be 30% or so faster for examples we have:

 Examples
decode
github-issues
lazy: OK (0.14s)
2.03 ms ± 168 μs
strict: OK (0.25s)
1.94 ms ± 180 μs
tokens: OK (0.34s)
1.27 ms ± 61 μs
Twitter
decode
Generic
direct
twitter100: OK (1.30s)
2.43 ms ± 161 μs
jp100: OK (0.25s)
2.09 ms ± 126 μs
twitter100t: OK (0.33s)
1.34 ms ± 121 μs
jp100t: OK (0.17s)
1.37 ms ± 86 μs
Manual
direct
twitter100: OK (0.21s)
1.76 ms ± 86 μs
jp100: OK (0.30s)
2.29 ms ± 207 μs
twitter100t: OK (0.74s)
1.38 ms ± 33 μs
jp100t: OK (0.20s)
1.61 ms ± 125 μs
TH
direct
twitter100: OK (0.27s)
2.08 ms ± 180 μs
jp100: OK (0.54s)
2.17 ms ± 149 μs
twitter100t: OK (0.36s)
1.38 ms ± 50 μs
jp100t: OK (0.39s)
1.48 ms ± 49 μs

The second point is also quite important.
If some users really need to know the order of key-value pairs in a JSON object, or care whether number was integral, decimal or scientific; now they can differentiate.

Though they cannot use FromJSON machinery, this is a start.

E.g. issues like Should we make a clear value-level distinction between floating and integral numbers?#546 (For Value it would be bad, for Tokens it's fine).

@phadejphadej mentioned this pull request Feb 9, 2023
@phadej

Copy link
Copy Markdown
CollaboratorAuthor

For now these additions would live only in Data.Aeson.Decoding. For next major we can replace ones in Data.Aeson with them.

@phadej
phadejforce-pushed the tokens branch 2 times, most recently from 20e4c54 to bed9420CompareFebruary 10, 2023 15:09
There are two motivation points:
1. it's faster
2. it's more expressive
The first point is actually accidental, but nevertheless very nice to
have. In benchmarks decoding strict bytestring through Tokens
seems to be 30% or so faster for examples we have:
```
Examples
decode
github-issues
lazy: OK (0.14s)
2.03 ms ± 168 μs
strict: OK (0.25s)
1.94 ms ± 180 μs
tokens: OK (0.34s)
1.27 ms ± 61 μs
Twitter
decode
Generic
direct
twitter100: OK (1.30s)
2.43 ms ± 161 μs
jp100: OK (0.25s)
2.09 ms ± 126 μs
twitter100t: OK (0.33s)
1.34 ms ± 121 μs
jp100t: OK (0.17s)
1.37 ms ± 86 μs
Manual
direct
twitter100: OK (0.21s)
1.76 ms ± 86 μs
jp100: OK (0.30s)
2.29 ms ± 207 μs
twitter100t: OK (0.74s)
1.38 ms ± 33 μs
jp100t: OK (0.20s)
1.61 ms ± 125 μs
TH
direct
twitter100: OK (0.27s)
2.08 ms ± 180 μs
jp100: OK (0.54s)
2.17 ms ± 149 μs
twitter100t: OK (0.36s)
1.38 ms ± 50 μs
jp100t: OK (0.39s)
1.48 ms ± 49 μs
```
The second point is also quite important.
If some users really need to know the order of key-value pairs
in a JSON object, or care whether number was integral, decimal or
scientific; now they can differentiate.
Though they cannot use `FromJSON` machinery, this is a start.
E.g. issues like *Should we make a clear value-level distinction between
floating and integral numbers?* #546
(For `Value` it would be bad, for `Tokens` it's fine).
@phadej

phadej commented Feb 10, 2023

Copy link
Copy Markdown
CollaboratorAuthor

The lazy bytestring token decoder is also fast, but slower than using strict bytestring as input.

All
Examples
decode
github-issues
lazy: OK (0.22s)
1.66 ms ± 114 μs
strict: OK (0.19s)
1.55 ms ± 96 μs
lazy tok: OK (0.32s)
1.23 ms ± 66 μs
strict tok: OK (0.13s)
1.02 ms ± 93 μs

@phadej

Copy link
Copy Markdown
CollaboratorAuthor

I also run the benchmark with libperf: less instructions and seems to be half of cache references, which may explain the speedup.

All
Examples
decode
github-issues
lazy: OK (0.04s)
10.3 M instructions
2.17 M branch instructions
54.0 K branch misspredictions (2.5%)
569 K cache references
62.5 K cache misses (11.0%)
strict: OK
6.96 M instructions
1.53 M branch instructions
41.4 K branch misspredictions (2.7%)
327 K cache references
42.7 K cache misses (13.1%)
lazy tok: OK
6.59 M instructions
1.54 M branch instructions
42.9 K branch misspredictions (2.8%)
245 K cache references
30.5 K cache misses (12.4%)
strict tok: OK
4.71 M instructions
1.11 M branch instructions
26.6 K branch misspredictions (2.4%)
157 K cache references
15.2 K cache misses (9.6%)
Twitter
decode
Manual
direct
twitter100: OK
5.86 M instructions
1.16 M branch instructions
27.5 K branch misspredictions (2.4%)
213 K cache references
27.5 K cache misses (12.9%)
jp100: OK
7.88 M instructions
1.63 M branch instructions
39.0 K branch misspredictions (2.4%)
275 K cache references
42.0 K cache misses (15.3%)
twitter100t: OK
4.21 M instructions
930 K branch instructions
23.2 K branch misspredictions (2.5%)
105 K cache references
17.8 K cache misses (16.9%)
jp100t: OK
4.93 M instructions
1.11 M branch instructions
25.5 K branch misspredictions (2.3%)
104 K cache references
15.8 K cache misses (15.1%)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@phadej