-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 compilation of a long list of values with different types #12915
Comments
possible duplicate of #7034? here is the type generated for val all:
List[
E[?
>: Int & String & List[Int] & List[String] & Double & (String,
String
) & (String, Int) & (Int, List[String]) & Long & (Long, Long) & (
Long
, Long, Int) & List[Long] & (String, String, String) & (String,
String
, Long) & (String, String, Boolean) & (Boolean, Boolean, String) &
List[(String, String)]
& List[(Int, String)] & List[(String, Int)] & List[(Long, String)]
&
List[(String, Long)] & List[(Boolean, String)] &
List[(String, Boolean)]
& List[((String, String), String)] & List[((String, Int), String)]
&
List[((Long, String), String)] & List[((Boolean, String), String)]
&
List[((String, String), (String, Int))] &
List[((Boolean, Long), (String, Int))]
& List[((Int, Long), (Boolean, Int))] &
List[((String, (Int, String)), (String, Int))]
& (Int, List[Int], Long) & (Int, List[Long], Long) & Char <: Int |
String
| List[Int] | List[String] | Double | (String, String) | (String,
Int
) | (Int, List[String]) | Long | (Long, Long) | (Long, Long, Int) |
List[Long]
| (String, String, String) | (Int, String) | (String, Long, String)
| (Long, String, String) | (String, String, Long) | (String, Int,
String
) | (Int, String, String) | (String, String, Int) | (String, String
,
Boolean) | (Boolean, Boolean, String) | (String, Int, Boolean) |
List[(String, String)]
| List[(Int, String)] | List[(String, Int)] | List[(Long, String)]
|
List[(String, Long)] | List[(Boolean, String)] |
List[(String, Boolean)]
| List[((String, String), String)] | List[((String, Int), String)]
|
List[((Long, String), String)] | List[((Boolean, String), String)]
|
List[((String, String), Int)] |
List[((String, String), (String, Int))]
| List[((Boolean, Long), (String, Int))] |
List[((Int, Long), (Boolean, Int))]
| List[((String, (Int, String)), (String, Int))] |
List[((Boolean, (Int, String)), (String, Int))]
| List[((String, (Int, String)), (Boolean, Int))] | (Int,
List[String]
, Long) | (Int, List[Int], Long) | (Int, List[Long], Long) | (String
,
List[String], Long) | (Int, List[String], Boolean) | Char
]
]
= List.apply[...](...) |
@bishabosha could be, though here we've got 50, not 5000 elements :) Also lists of 50 heterogenous elements probably occur much more frequently than lists of 5000 ;) So maybe this variant will be easier to debug & fix. |
as a workaround, this compiles much quicker (sorry if you are cross compiling) ...
val all0 = (e1, e2, ..., e49) // aka huge tuple
val all = all0.toList // all0 needs to be in another variable to improve performance |
@bishabosha this didn't help - I still got 215 second compile time, but this time failed with an error with some long union type. But I divided the list into sublists of length 10, then I combine all of these, and now it compiles quite quickly (softwaremill/tapir@109908f) |
another way I think to speed up is to widen each argument to whichever common supertype you want, val all = List(
e1: E[?],
e2: E[?],
e3: E[?],
...
e47: E[?],
e48: E[?],
e49: E[?]
) |
Or |
Ha! Of course 🤦 Thanks :) |
it's a nasty problem for the type inferencer since it ends up with a constraint where the lower bound of a type variable consists of an And with 50 types and the upper bound consists of an Or with 50 types. That's twice the worst case. It's efficient to deal with OrTypes on the left and AndTypes on the right, but the other way round causes backtracking and costly comparisons of constraints. but it should not be that bad, to the degree that a single list requires 32 or 250 seconds. I managed to fix the problem by balancing AndTypes and OrTypes when we create them in a lub or glb. This brings down the time of the test to 4 seconds on my machine. I have not analyzed yet where the slowdown went before, but it looks generally like a good idea to avoid unbalanced trees. |
Compiler version
3.0.1-RC2
Minimized code
Output
Takes 32 seconds to compile locally. A similar list in tapir with 87 elements takes 250 seconds. Shorter lists behave normally, but at some point the compile times explode. The types of the elements on the list must be different - if it's all e.g.
E[String]
then compilation is fast. I suspect something in the type inferencer grows exponentially.Expectation
Shorter compile time :)
The text was updated successfully, but these errors were encountered: