-
-
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
Switch to using __dict__ instead of __values__ (up to 14x speedup, lower model size) #711
Comments
This is very interesting! I tried running the benchmark, and it looks like there is no change, but I think the benchmark only relates to parsing speed (basically no I added the following code to the benchmark to see what it looked like in a slightly more realistic usage scenario: passed, result = test.validate(case)
# New here:
if passed:
for _ in range(200):
if result.location is not None:
getattr(result.location, "latitude") If I remove the contribution of the parsing part, I got an approximately 10x speedup on your branch relative to master, whether cythonized or not. As far as I can tell, there was no regression in parsing speed. However, if I replaced the above getattr with just At any rate, given how common an operation attribute access is in practice, this seems like an awesome improvement! There is another big benefit to this (at least for us PyCharm users 😅): by removing the custom
So it sounds like they have no intention of changing the behavior. Just the fact that this change fixes the lack of getattr warnings in PyCharm alone would be enough to get me excited about this change. Overall, 👍👍 |
I noticed that I guess that is because we acessing And yeah, glad to hear it solves one of PyCharm issues 😄. |
This looks awesome. Thank you very much. I'll review the code in the PR but reply to the principle here. I don't think we need to add the |
fixed by #712 |
Question | Feature Request
Recently I've been researching how
__dict__
and__slots__
works and discovered that if we inherit from class with__slots__
and don't declare__slots__
in child class,__dict__
will be created automatically.Also I found out that
object.__dict__
uses less memory than ordinal dict, as it shares keys between instances (PEP-0412)Moreover I found an advice to use
__dict__
and__slots__
together in cases when fast access to attributes declared in__slots__
needed.So combining these researches I replaced
__slots__ = ('__values__', '__fields_set__')
with
__slots__ = ('__dict__', '__fields_set__')
and renamed usages of
__values__
inBaseModel
(yes, that's exactly the only thing I've made)also removed__getattr__
, as it's become redundant.To see up-to-date changes, visit #712
This lowered model size a bit, but what is most interesting, increased attribute access up to 14 times (average speed up is 10x)!
All tests are passed without any changes, so as far as I know this won't break any existing code except for one that uses
__values__
attribute directly. But I guess that can be solved by adding a property:Here's a little test showing a difference:
Results with
__values__
used in BaseModel:Result with
__dict__
used instead of__values__
(upd. results without getattr):The text was updated successfully, but these errors were encountered: