Conversation
917ddd1 to
0534f31
Compare
CodSpeed Performance ReportMerging #14024 will degrade performances by 4.32%Comparing Summary
Benchmarks breakdown
|
|
| (Type::Instance(self_class), Type::Instance(target_class)) | ||
| if self_class.is_known(db, KnownClass::NoneType) => | ||
| { | ||
| target_class.is_known(db, KnownClass::NoneType) | ||
| } |
There was a problem hiding this comment.
We should be able to remove this branch too once we understand that NoneType is a subclass of object (my MRO PR is coming soon!!)
There was a problem hiding this comment.
Note that this is about NoneType <: NoneType. The X <: object case is handled further above.
I'm actually surprised that NoneType <: NoneType doesn't work without this. We have a other == self check in is_subclass_of on the ClassTypes. Is that not working correctly? Is it actually checking for equal classes or for some other identity. Like just comparing salsa IDs?
my MRO PR is coming soon!!
That will definitely help us remove some cases!
There was a problem hiding this comment.
self == other is indeed just checking salsa IDs. But Salsa IDs are assigned by Salsa interning, which interns based on struct equality, so that should be the same thing as an Eq check.
It would be good to understand what's happening here. Let me know if you'd like another pair of eyes on it. Maybe it's related to the fact that there are multiple NoneType in typeshed? (The one in _typeshed and the one in types for more recent Python versions.)
Also, I think this branch should go into is_equivalent_to instead of is_subtype_of.
0ff025a to
1735975
Compare
carljm
left a comment
There was a problem hiding this comment.
Looks great!
I wonder how much of the perf regression is due to the fact that currently I think every None ends up being a union of the None defined in _typeshed and the one defined intypes? This could mean we spend a lot more time in recursive union handling for things like is_subtype_of? If so, this should be largely mitigated by sys.version_info checking.
| (Type::Instance(self_class), Type::Instance(target_class)) | ||
| if self_class.is_known(db, KnownClass::NoneType) => | ||
| { | ||
| target_class.is_known(db, KnownClass::NoneType) | ||
| } |
There was a problem hiding this comment.
self == other is indeed just checking salsa IDs. But Salsa IDs are assigned by Salsa interning, which interns based on struct equality, so that should be the same thing as an Eq check.
It would be good to understand what's happening here. Let me know if you'd like another pair of eyes on it. Maybe it's related to the fact that there are multiple NoneType in typeshed? (The one in _typeshed and the one in types for more recent Python versions.)
Also, I think this branch should go into is_equivalent_to instead of is_subtype_of.
|
I took a look at the perf regression What I spotted is that this branch now spends 5.6% of total time inside Expanding the tree shows that the difference comes from @lru_cache(maxsize=None)
def cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone:
sign = 1 if sign_str == "+" else -1
return timezone(
timedelta(
hours=sign * int(hour_str),
minutes=sign * int(minute_str),
)
)Inside I tried to debug if we now infer a more accurate type for from functools import lru_cache
from typing import reveal_type
reveal_type(lru_cache(maxsize=None))The main thing that's puzzling me.... Why is the Ohh... never mind. I looked at the warmup phase instead of the incremental path. This is for the incremental part The finding is the same... and, for some reason, |
|
Looking at the salsa code. What this suggests is that we don't reuse the same salsa ids and, because of that have cache misses... |
|
I'm not sure what's happening and/or if this is a bug in the benchmark. I copied the tomllib and manually ran the red knot CLI in watch mode and the salsa events indicate that it uses the memoized values except for |
|
Okay, I might still have looked at the wrong profiles. I now created a PR to use a named closure for the incremental and warmup vs to avoid this in the future. I haven't looked at it too closely because salsa's maybe changed after profiles are a bit of a pain but I strongly suspect that the difference mainly comes from that salsa now has to validate the ingredients for the module defining |
Is this a speculation or is there evidence pointing to it? I couldn't really follow which comments here are based on looking at the wrong part of the profile :) This could be, though. I was thinking we would already have a dependence on If this is the cause of the regression, it's mostly just a weakness in our benchmark. Real-world codebases are likely to already rely on the I still think it's worth seeing whether Salsa-caching the resolution of the type of |
f5f010f to
c7d4bdb
Compare
Performance investigation
This also explains why I didn't see a performance regression when comparing this branch with main on a larger codebase (
After talking to @MichaReiser, I removed the explicit caching of the |
503aa46 to
c7d4bdb
Compare
* main: (39 commits) Also remove trailing comma while fixing C409 and C419 (astral-sh#14097) Re-enable clippy `useless-format` (astral-sh#14095) Derive message formats macro support to string (astral-sh#14093) Avoid cloning `Name` when looking up function and class types (astral-sh#14092) Replace `format!` without parameters with `.to_string()` (astral-sh#14090) [red-knot] Do not panic when encountering string annotations (astral-sh#14091) [red-knot] Add MRO resolution for classes (astral-sh#14027) [red-knot] Remove `Type::None` (astral-sh#14024) Cached inference of all definitions in an unpacking (astral-sh#13979) Update dependency uuid to v11 (astral-sh#14084) Update Rust crate notify to v7 (astral-sh#14083) Update cloudflare/wrangler-action action to v3.11.0 (astral-sh#14080) Update dependency mdformat-mkdocs to v3.1.1 (astral-sh#14081) Update pre-commit dependencies (astral-sh#14082) Update dependency ruff to v0.7.2 (astral-sh#14077) Update NPM Development dependencies (astral-sh#14078) Update Rust crate thiserror to v1.0.67 (astral-sh#14076) Update Rust crate syn to v2.0.87 (astral-sh#14075) Update Rust crate serde to v1.0.214 (astral-sh#14074) Update Rust crate pep440_rs to v0.7.2 (astral-sh#14073) ...


Summary
Removes
Type::Nonein favor ofKnownClass::NoneType.to_instance(…).closes #13670
Test Plan
Existing tests pass.