Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:(ast) Node support concurrently-read #661

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

AsterDY
Copy link
Collaborator

@AsterDY AsterDY commented Jun 25, 2024

Background

Since sonic uses Lazy-Load design to parse JSON nodes on demands, it doesn't support concurrently-Read by default. But in practice, we found many users may use it in such scenarios and cause panic.

Desgin

Thus we design one kind of State Transition Lock to achieve the goal by least cost. In brief:

  • Drop the Lazy state (parse transversely on demands). Every node has only two state: Parsed (bool, number, or object slice...) or Raw (JSON), and the only transit direction is Raw->Parsed;
  • Every exported reading API (like Get()) will check its state using Atomic Load:
    • If in Raw, transfer to Parsed with Write Lock
    • If in Parsed, the state won't change forever, just use if safely
    • Except for encoding the Node (Raw() and MarshalJSON()). In these circumstances, we need keep the Raw state to achieve the best performance. Thus use Read Lock to keep the state.

Performance

  • Since the first layer of children of each complex node (object or array) will be loaded, it will have influence on performance of Get, about 5~10%. Thus we not enable it by default, except user manually set SearchOption.ConcurrentRead=true or create JSON node by NewNodeSafeRead() or call Node.LoadAll()/Load()
goos: darwin
goarch: amd64
pkg: github.com/bytedance/sonic/ast
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkGetOne_Sonic-16                          878953              1308 ns/op        9953.59 MB/s          32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                         1000000              1182 ns/op        11016.84 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                          831817              1232 ns/op        10569.39 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                          979562              1198 ns/op        10870.91 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                          930523              1189 ns/op        10956.22 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                         1000000              1215 ns/op        10718.41 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                          974142              1222 ns/op        10656.71 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                         1000000              1245 ns/op        10456.85 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                          971686              1227 ns/op        10610.24 MB/s         32 B/op          1 allocs/op
BenchmarkGetOne_Sonic-16                          981230              1214 ns/op        10729.66 MB/s         32 B/op          1 allocs/op
BenchmarkGetOneSafe_Sonic-16                      938812              1268 ns/op        10271.51 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      947300              1295 ns/op        10056.15 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                     1000000              1230 ns/op        10588.26 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      964974              1291 ns/op        10091.09 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      878860              1243 ns/op        10474.22 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      872864              1348 ns/op        9660.36 MB/s          56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      987982              1287 ns/op        10121.73 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      922160              1271 ns/op        10248.48 MB/s         56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      817058              1324 ns/op        9833.82 MB/s          56 B/op          2 allocs/op
BenchmarkGetOneSafe_Sonic-16                      882301              1312 ns/op        9929.62 MB/s          56 B/op          2 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                5727440               235.7 ns/op      55255.37 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                5369863               222.4 ns/op      58564.43 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                5203185               254.3 ns/op      51212.89 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                4898695               236.3 ns/op      55113.17 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                5038414               254.2 ns/op      51234.39 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                5049417               246.0 ns/op      52936.09 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                4310595               245.7 ns/op      52994.69 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                4627548               281.7 ns/op      46226.08 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                4450712               285.6 ns/op      45595.73 MB/s         33 B/op          1 allocs/op
BenchmarkGetOne_Parallel_Sonic-16                3638448               306.8 ns/op      42443.90 MB/s         33 B/op          1 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            3879680               343.8 ns/op      37878.47 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            3738738               303.9 ns/op      42848.85 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            3650202               323.0 ns/op      40324.44 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            4087995               323.1 ns/op      40303.63 MB/s         60 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            4072354               294.7 ns/op      44189.79 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            4057981               338.9 ns/op      38431.59 MB/s         58 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            3879730               338.4 ns/op      38488.79 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            3642368               328.8 ns/op      39605.56 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            4007350               333.7 ns/op      39023.50 MB/s         59 B/op          2 allocs/op
BenchmarkGetOneSafe_Parallel_Sonic-16            4022107               332.6 ns/op      39155.85 MB/s         59 B/op          2 allocs/op

@AsterDY AsterDY changed the title feat:(ast) support concurrently-read feat:(ast) Node support concurrently-read Jun 27, 2024
@codecov-commenter
Copy link

codecov-commenter commented Jun 27, 2024

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 75.70850% with 60 lines in your changes missing coverage. Please review.

Project coverage is 71.58%. Comparing base (99f5b35) to head (95e7de9).
Report is 17 commits behind head on main.

Files Patch % Lines
ast/node.go 77.57% 14 Missing and 10 partials ⚠️
ast/buffer.go 68.88% 11 Missing and 3 partials ⚠️
ast/parser.go 81.66% 9 Missing and 2 partials ⚠️
api.go 0.00% 4 Missing ⚠️
ast/iterator.go 55.55% 1 Missing and 3 partials ⚠️
ast/search.go 70.00% 2 Missing and 1 partial ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

❗ There is a different number of reports uploaded between BASE (99f5b35) and HEAD (95e7de9). Click for more details.

HEAD has 5 uploads less than BASE
Flag BASE (99f5b35) HEAD (95e7de9)
7 2
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #661      +/-   ##
==========================================
- Coverage   77.56%   71.58%   -5.98%     
==========================================
  Files          83      101      +18     
  Lines       11542     8194    -3348     
==========================================
- Hits         8952     5866    -3086     
+ Misses       2192     2012     -180     
+ Partials      398      316      -82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@AsterDY AsterDY force-pushed the feat/ast_lock branch 3 times, most recently from 6f06741 to a4d6b6b Compare June 29, 2024 11:26
Sign up for free to 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.

None yet

2 participants