-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Very slow evaluation of recursive types #7149
Comments
Great work investigating the issue! I can confirm that with the proposed change all tests pass, but @adriangb this is your code and I figure you might be quicker to understand the implications? @mciucu I think it's a good idea to open a PR for this either way, please feel free, very much appreciated. |
This generally looks good. I added some pretty in depth tests precisely with the idea that I'd TDD that code at the time and someone would come along and improve it later :). Let's take a careful look at the tests and make sure they cover all of the cases, in particular around those LOC, and add more if needed. If that works I'm very positive for this change. |
I've created a pull request with the change. I think maybe a test based on the structure I had in that example code would help catch any performance regressions in the future, since that snipped takes about 5 minutes to run for me locally (so it seemed like it was O(N!)). I can add here anything if it would be helpful, was just not sure how benchmark tests are implemented in pydantic. |
This is preventing us from migrating to v2, as our models take more than 10 minutes (!!!!) to rebuild. Would be great to identify a fix, and cut a release so we can bump versions and enjoy the performance of Rust! :) |
The pull request was merged, this will come out in the next release. |
Initial Checks
Description
I've tracked it down to the inner function
count_refs
in_core_utils.py
, that seems to be doing at least quadratic work than what would be required. With ~10 classes that could be recursively included inside one another in a tree I'm getting ~1 minute execution on callingmodel_rebuild()
for all.The change that I think would be safe and efficient would be change lines 464-467 with:
This should be safe, given that if a model X can contain itself the second time when entering the
count_refs
function should be directly or indirectly from an inclusion where model X is already in the call stack.Call time for
model_rebuild()
is <1s now.I can make a pull request if that's ok.
Example Code
Python, Pydantic & OS Version
Selected Assignee: @davidhewitt
The text was updated successfully, but these errors were encountered: