Optimize classpath implementation to speed up SBT#5956
Optimize classpath implementation to speed up SBT#5956retronym merged 2 commits intoscala:2.12.xfrom
Conversation
1b72ec3 to
0ef7185
Compare
|
LGTM! Perhaps not directly related, but still in this area of the code: we need to provide a classpath implementation in our codebase and it would be very helpful to widen the visibility of some classes/methods. They don't seem to be consistently If that has chances to be merged I'm happy to open a PR. |
| } | ||
|
|
||
| val classEntry = findEntry(isSource = false) | ||
| val sourceEntry = findEntry(isSource = true) |
There was a problem hiding this comment.
You could search for both entries in a single traversal, but it's probably not going to make a difference, as there are few aggregates for a given package.
I think that should be fine. |
|
@dragos I'm open to opening up access in those cases. I think some of the cases you pointed out can be cleaned up by referring to the public types, as in https://github.com/retronym/scala/tree/topic/refactorClassPath |
Interestingly, the dotty sbt phases do not use |
|
We should give this a spin through the community build before merging.
@smarter My patch seemed to have the correct behaviour, but didn't seem to improve performance in my test as I had expected. |
So |
|
Hi @retronym as discussed directly, I have some work in this area. Happy to share I have a classpath cache that can use a file watcher to detect changes This is showing a 20% reduction in memory allocation and around 10% in CPU I think that my chnages should work well with yours - I have not been changing the AggregateClassPath, but focussed on the other structures. raw figures |
|
/rebuild |
0ef7185 to
06ef85c
Compare
The best theory is that I've made some silly error in my attempt to modify SBT and/or my attempt to measure the difference. My gut feel is still that switching to |
|
/synch |
06ef85c to
109f46f
Compare
|
Rebased and made a minor reversion of a change of signature to quiet MiMa, and tried again to schedule a community build at https://scala-ci.typesafe.com/job/scala-2.12.x-integrate-community-build/1621/ |
|
Testing this locally in the Akka SBT build has flushed out a problem. |
Sigh, it slipped through my fingers and I can't reproduce now. Will see how the community build fares and try to retrace my steps locally in the Akka build. Marked as WIP so we don't merge just yet. |
|
/synch |
- Rather than `findAll.filter(_.name == name)`, just lookup the entry with the right name to start with. - Avoid a linear scan of aggregate classpath by building and index keyed on package names
109f46f to
bd73417
Compare
| * | ||
| * Externally, it is used by sbt's compiler interface: | ||
| * https://github.com/sbt/sbt/blob/v0.13.15/compile/interface/src/main/scala/xsbt/CompilerInterface.scala#L249 | ||
| * Jason has some improvements for that in the works (https://github.com/scala/bug/issues/10289#issuecomment-310022699) |
There was a problem hiding this comment.
could remove parts of this comment
That turned out to be unrelated to this PR, and has been fixed separately in #5976. |
Zinc 1.0 already checks for |
Original author is @retronym in scala/scala#5956
Original author is @retronym in scala/scala#5956
Original author is @retronym in scala/scala#5956
Adapted from scala commits b9520211b22e53d4f80801b0f64cdb6275ac55cf and bd7341754f8aec4ddbf455544eb393ff6cf4a43a by Jason Zaugg and Lukas Rytz in scala/scala#5956: - Rather than `findAll.filter(_.name == name)`, just lookup the entry with the right name to start with. - Avoid a linear scan of aggregate classpath by building and index keyed on package names
Adapted from scala commits b9520211b22e53d4f80801b0f64cdb6275ac55cf and bd7341754f8aec4ddbf455544eb393ff6cf4a43a by Jason Zaugg and Lukas Rytz in scala/scala#5956: - Rather than `findAll.filter(_.name == name)`, just lookup the entry with the right name to start with. - Avoid a linear scan of aggregate classpath by building and index keyed on package names
Adapted from scala commits b9520211b22e53d4f80801b0f64cdb6275ac55cf and bd7341754f8aec4ddbf455544eb393ff6cf4a43a by Jason Zaugg and Lukas Rytz in scala/scala#5956: - Rather than `findAll.filter(_.name == name)`, just lookup the entry with the right name to start with. - Avoid a linear scan of aggregate classpath by building and index keyed on package names
SBT is a heavy user of
Classpath.findClass, and its performance regressed, especially for large classpaths, under the new "flat" classpath implementation. The new implementation shipped in 2.11 experimentally (-YclasspathImpl:flat), and was promoted to the default an only implementation in 2.12.In 2.12, the performance was improved some in 0f9a704 / #5112. This commit goes further by optimizing the lookup of a given class in a JAR classpath entry, and, most importantly, by avoiding a linear scan of the classpath on each lookup by indexing which classpath entries contribute classes to each package.
I tested a 2.11 backport of this patch using https://github.com/guardian/frontend as a test case.
Results: https://gist.github.com/3c89c21c54d27e566dec57a16a4bf208
tl;dr; No significant difference in performance between the classpath implementations after this change. The baseline performance was 55s, which regressed to 79s under
-YclasspathImpl:flatand then progressed back to 55s using the same flat classpath implementation as in this PR.I've also tried to patch SBT to use
Symbol.associatedFilerather than scanning the classpath, but I haven't got that change into shape yet.Fixes scala/bug#10289