-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Create a copy of TypeQuery specialized for bool #9604
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
Conversation
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.
This looks solid. The one question is whether we think it helps enough to be worth the extra code. I had one suggestion for a potential perf improvement, so try that out.
Also, it looks like you accidentally included a typeshed submodule update.
mypy/type_visitor.py
Outdated
self.seen_aliases = set() # type: Set[TypeAliasType] | ||
|
||
def bool_strategy_empty(self) -> bool: | ||
if self.strategy == self.STRATEGY_ALL: |
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.
Try accessing the constants as TypeQueryBool.STRATEGY_ALL
instead. mypyc should directly emit a constant in that case, and it'll emit an object lookup for self
. (That's probably a bug.) The object lookup should be cheap, but is still a memory access and an error check, so the constant might be better.
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.
👍
mypy/type_visitor.py
Outdated
|
||
# TODO: check that we don't have existing violations of this rule. | ||
""" | ||
STRATEGY_ANY = 0 # type: Final[int] |
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.
Shouldn't it be just : Final
?
from typing_extensions import Final
class Test(object):
a = 1 # type: Final
b = 2 # type: Final[int]
reveal_type(Test.a) # Revealed type is 'Literal[1]?'
reveal_type(Test.b) # Revealed type is 'builtins.int'
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.
The doc says that if we omit the type, mypy infers it
https://mypy.readthedocs.io/en/stable/final_attrs.html#syntax-variants
I don't know what conclusion to draw from your example, is it better to have a Literal or builtins.int?
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.
I am not sure about the mypy team, but I personally prefer Literal, because it is more specific. And constants should be specific. 👍
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.
I changed them to Final 👌
@@ -347,3 +349,121 @@ def query_types(self, types: Iterable[Type]) -> T: | |||
self.seen_aliases.add(t) | |||
res.append(t.accept(self)) | |||
return self.strategy(res) | |||
|
|||
|
|||
class TypeQueryBool(SyntheticTypeVisitor[bool]): |
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.
Related: #9602
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.
thanks for the headsup, I added the decorator for allow_interpreted_subclasses=True
Does this change the perf impact at all? |
I tried a few runs and I didn't see any perf impact, I have the exact same run times. The accuracy of my bench is probably not good enough to catch this kind of improvement |
I agree, it's not clear if it's worth it. I want to give another shot at benchmarking this in the next few days. |
Thanks for investigating this! Seems like we weren't able to get this to a point where it was worth it, so closing. But perf work / investigation is always appreciated :-) |
Description
I tried implementing the optimization described in #7128.
I created
class TypeQueryBool(SyntheticTypeVisitor[bool])
.It's a specializedTypeQuery
,imlementating.
all
orany
strategies.Some code and comments are duplicated, so I'm not entirely satisfied with the implementation.
I'm opening the PR for some review about the implementation and the testing method.
Test Plan
I forked
mypy_mypyc-wheels
project and I built mypyc wheels with travis, to benchmark.I used
v0.800+dev.952ca239e6126aff52067a37869bd394eb08cf21
as the reference, and compared it with my exact changes added on top: https://github.com/vbarbaresi/mypy_mypyc-wheels/releases/tag/v0.800%2Bdev.f7129b21I'm using macOS 10.15, python 3.8.6 and the following benchmark script (I know it's not ideal because it counts the startup time of the python process):
I tried switching the order, running my branch first, then mypy master.
I wasn't able to get a 0.2 % accuracy, so I'm not entirely confident in the results.
I ran this bench more than 10 times and observed my branch performing very slightly better in a lot of runs
Typical run results:
On some other runs the mean was 10.9 sec for my branch, and still 11.0 on master (but always with +- 0.1 sec std dev)