-
Notifications
You must be signed in to change notification settings - Fork 267
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
Memory usage optimization via reuse of SchemaValidator
and SchemaSerializer
#1616
Conversation
CodSpeed Performance ReportMerging #1616 will not alter performanceComparing Summary
|
Impressive! I hope you will not stop here. |
SchemaValidator
and SchemaSerializer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine enough! I wonder, is there a way this can be tested? Maybe do something evil like modify the __pydantic_validator__
on a type and confirm that validator is picked up? 🙈
Wondering if I should consolidate the shared "extract prebuilt" logic between the validator and serializers... |
I think that would be smart, suggest file to go at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, feel free to consolidate logic and then merge 👍
The main goal of this PR is to reduce memory usage associated with models by minimizing how much space
SchemaValidator
s andSchemaSerializer
s consume.This is done by reusing references to existing validators and serializers when there are nested structures present.
This is allowed for
model
and (pydantic)dataclass
core schemas. Notably, we don't use this reuse pattern for generic dataclasses (see code commentary for more info).This has been benchmarked against many examples. The examples where this refactor has the most impact are those which have lots large/nested models.
Two examples where improvements were particularly noticeable were for schema builds with:
Some highlight stats:
aiotdlib
, and a small 3-5% improvement for the kubernetes example.For
aiotdlib
on
main
:with this branch:
Old flamegraph:

New flamegraph:

For
k8s_v2.py
on
main
:On this branch:
Old flamegraph:

New flamegraph:

Thanks 🚀
@Viicos with the help finding some examples that were appropriate for benchmarking, and the idea to skip the core schema modifications for simplicity 👍
@davidhewitt for iterating with me on the appropriate pyo3 tools to use for this :)
@BoxyUwU for your work on #1414 which got us started down this path