Repository navigation
Conversation
One component, figure or pd.Timestamp in a response made plotly's to_json_plotly walk the whole payload in Python (#4065). Use orjson with a default hook when installed, otherwise msgspec, and fall back to plotly on any error.
Contributor
Dash performance benchmarks
growth = late-third / early-third per-op time; ~1 is flat, a large value means the per-op cost scales with accumulated state. machine scale vs baseline: 0.61x - divided out of the baseline ratios so they compare like for like (the absolute warn/fail ceilings are left un-scaled); calibrated on |
2 tasks done
Contributor
|
Ah yes I noticed this, having orjson installed was sometimes slower than without it! Glad to see it being addressed! |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #4065.
With orjson installed, plotly's
to_json_plotlydumps the whole payload, and if one value is not orjson-native (a component, ago.Figure, apd.Timestamp) it walks every value in Python and dumps again. Layouts always take that path. Without orjson, everything goes through the stdlib walk.dash._utils.to_jsonnow goes through a newdash/_json.py:orjson.dumpswith adefault=hook, so only the values orjson can't take are converted."json"): msgspec, which Dash already depends on through shared storage, with the same kind of hook.to_json_plotly, so errors and callback validation messages stay the same.Numbers
From the serialization benchmark in #4055, 10 traces x 20k points, median ms:
Payloads that were already orjson-native take the same time as before (the hook is never called).
The
go.Figure/ layout rows are still bound byto_dict()'s deepcopy in plotly. That needs a plotly.py change (a_to_json_dictthat skips the copy) and will be a follow-up.Output differences
datetime64inside a figure, which now always uses orjson's short form (2024-01-01T00:00:00), as plotly's fast path already did. A datetimepd.SerieswithNaTnow serializes (plotly raised).datetimegives...Zinstead of+00:00.timedeltaandnp.timedelta64serialize instead of raising.np.datetime64scalars give an ISO string, non-ASCII is emitted raw.msgspec.Raw, about 1 ms per 8 MB) and anything invalid goes to plotly. Non-finite Decimals andnp.datetime64('NaT')givenull, and circular values raiseValueError, as in plotly's json engine.Tests
tests/unit/test_json.py: parity with plotly on both engines, a test that counts values visited by plotly's slow walk (fails before the fix), NaT handling, and unserializable values still raisingTypeError, and non-finite / circular values matching plotly.tests/integration/callbacks/test_serialization.py: an app returning a figure, a component and apd.Timestampin one response, on both engines.plotly/plotly.py#5813 removes the
go.Figuredeepcopy and adds a msgspec engine to plotly itself. Once it ships, a follow-up here can call_to_json_dict()instead ofto_plotly_json()for figures, so the figure and layout rows above drop to the figure-alone time.