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
Grab bag of compiler optimizations #3445
Conversation
Avoid the Applied extractor altogether, as that eagerly creates `argss` which we don't need and which is quite expensive.
It's called rather frequently. Tree#symbol is a megamorphic call, which featured in profiles.
Anything we can do to make erasure faster.
isPossibleRefinement reported as 1% of my profile, about half of that was reported from the `EraserTyper`. This commit restricts `checkMethodStructuralCompatible` to the typer phase, and also moves in the feature warning for implicits which was nearby. I've also made a minor optimization to `overriddenSymbol` by avoiding computing the method schema repeatedly.
@@ -861,7 +861,7 @@ private[internal] trait TypeMaps { | |||
class InstantiateDependentMap(params: List[Symbol], actuals0: List[Type]) extends TypeMap with KeepOnlyTypeConstraints { | |||
private val actuals = actuals0.toIndexedSeq | |||
private val existentials = new Array[Symbol](actuals.size) | |||
def existentialsNeeded: List[Symbol] = existentials.filter(_ ne null).toList | |||
def existentialsNeeded: List[Symbol] = existentials.iterator.filter(_ ne null).toList |
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.
Even faster (typically) is
{ val lb = List.newBuilder[Symbol]; existentials.foreach(x => if (x ne null) lb += x); lb.result }
and faster still is
{ val lb = List.newBuilder[Symbol];
var i = 0
while (i< existentials.length) {
val x = existentials(i)
if (x ne null) b += x
i += 1
}
lb.result
}
How big of a bottleneck is this? Is it worth going that low-level?
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 patch was enough to take this off my profiling radar. It was a bottleneck, but only in one of the dozens of bottles I was looking at. :)
Creating a throwaway Array
(generically) was the drastically expensive thing I wanted to avoid.
From a performance perspective, LGTM aside from the issue I highlighted above. |
Avoid creating a throwaway array in existentialsNeeded.
Shadowing is rarer than implausbility; this seems to be the most efficient way to order these filters.
Use `hasAttachment` rather than `getAttachment.exists`
Cache it, rather than recreating it for each candidate overriden method we encounter. We can't do this eagerly as we trip a cycle in neg/t5093.scala.
Just pushed a fix for the bad apple, "Optimize use of methodTypeSchema", and moved it do the end of the commit list. Other commits are unchanged. |
PLS SYNCH |
(kitty-note-to-self: ignore 33877495) |
Grab bag of compiler optimizations
@gkossakowski This work comes from my branch that we
went through in Lausaunne a few months back.
Sorry I was so slow to submit this as PRs. I had hoped
to find more time to robustly benchmark, but you know
how it goes...
When I tried, your benchmark tool showed the usual
problems of saying anything conclusive about individual
commits, but the trend over the entire series unambigious.
The entire series showed ~30% delta for FSC-style compilation,
~20% for SBT-style (new Global instance each compilation batch.)
I'm trying to submit what I consider to be uncontroversial
changes in groups. If a particular change requires deeper
review, I'll submit it individually.
/cc @Ichoran