-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Arithmetic operations with inferred variables take quadratic time to type-check #25916
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. Having ran callgrind on the sample and also half of it, I'm seeing the following trace:
An unrefined conclusion is that either |
The `HashMap` and `HashSet` iterators use `RawTable::first_bucket_raw` which is generic and will get inlined cross-crate. However, `first_bucket_raw` calls `calculate_offsets` and the call doesn't get inlined, despite being a simple function. This missing `#[inline]` results in `hash_table::calculate_offsets` showing up at the top of a callgrind profile with 3 million calls (for the testcase in rust-lang#25916).
Is this the same issue as #23977? |
@nikomatsakis I'm not too familiar with fulfill and infer, but couldn't |
The `HashMap` and `HashSet` iterators use `RawTable::first_bucket_raw` which is generic and will get inlined cross-crate. However, `first_bucket_raw` calls `calculate_offsets` and the call doesn't get inlined, despite being a simple function. This missing `#[inline]` results in `hash_table::calculate_offsets` showing up at the top of a callgrind profile with 3 million calls (for the testcase in #25916).
We have |
This speeds up rustc on #25916 from 1.36Â0.022s to 1.326Â0.025s
This speeds up rustc on rust-lang#25916 from 1.36±0.022s to 1.326±0.025s Tests pass locally (even on 32-bit :-)
Basically fixes rust-lang#25916
this improves typeck performance by 5% (LLVM times are still huge). Basically fixes #25916 (still O(n^2), but the example takes <1s to compile).
this improves typeck performance by 5% (LLVM times are still huge). Basically fixes #25916 (still O(n^2), but the example takes <1s to compile). r? @nikomatsakis
This takes ~2 seconds to type check (according to
-Z time-passes
):Doubling (respectively, halving) the number of
f!()
invocations multiplies (resp. divides) the time by 4.It applies to arithmetic in
const
s/static
s too which is, I imagine, where this will occur most often in practice (it's how I found it).Observations:
+
,-
,*
and/
, annotating either side (e.g.0 + 0u8
) or both sides makes it take only 0.03s and behave linearly (AFAICT)<<
and>>
:0u8 >> 0
) reduces the time to ~1.5s,0 >> 0u8
) reduces it to ~1.1s but both are still quadratic,f!
to allow easier experimentation)cc @rust-lang/compiler
The text was updated successfully, but these errors were encountered: