-
-
Notifications
You must be signed in to change notification settings - Fork 355
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
review: Use matching package with most contained types #4139
review: Use matching package with most contained types #4139
Conversation
Okay, the version in this PR is slightly optimized (max instead of reverse sorting) and clocks in at ~ the same time for projects without modules (it shouldn't do anything extra there, as the comparator is not called for single element streams and we should not have duplicates there) and slows down JDK indexing by ~40 seconds (so ~20%). That is probably more acceptable, though I don't know where the slowdown even comes from. Maybe it increases the lock contention on the concurrent skip list map. Though running it with one instead of 8 threads (I have an 8 thread CPU) yields:
The output without this PR is wrong though and correctness trumps performance, it just looks so weird. If you want I can detail the steps you'd need to do to try to reproduce this but your time is probably quite a bit more valuable. |
Most of the slowdown is due to the following: With the comparator java needs to evaluate I optimized the The last commit (
Code without modules is not affected at all from this PR as far as I can see (see here):
|
e1b82d3
to
6c83152
Compare
Thanks! The optimization is good, but I'm not sure we need a new method in the interface. WDYT? |
That only exists to prevent a useless set copy from being created every time, but I think with some stuff from SirYwells PR we can sidestep that issue and maintain the cleaner API. I will remove that method in this PR, we can always re-add some smarter set creation later on. |
LGTM. Could you document the core idea and contract also directly in the methods in |
While writing the comment you requested I noticed a possible simplification: Sadly, this does not seem to be part of the java spec but is something I could:
I would prefer What do you think? |
I'm not quite sure what to make of that. |
Right, I misremembered that. Then we are kinda screwed, no? If we need to look up a type we'd need to give that information to the This PR is probably fine as-is then but only addresses the problem partially. Using the package with most types might statistically have a few more hits than taking the first, but I am not sure that's worth it... |
Well, in terms of compile time, I suppose so. But as the module system system doesn't seem to be onboard with overlapping packages at runtime, I think it's pretty safe to assume that no one will write code like that in a single project. That being said, it shouldn't be particularly expensive to check for overlap and throw an exception if there is overlap, right? I think doing that would be a nice safeguard, and good for usability in case someone does something crazy, or we have misunderstood something about the module system. |
I had that originally but JDT seems to allow having overlapping packages and that caused the exception to trigger. If you are fine with rejecting such code I will re-add the check. EDIT: I accidentally broke the implementation with the first commit after this comment, but the tests will pass nonetheless. That is because my code works if the last package is correct and the original code works if the first one is correct. Should I add a test with the reverse order as well? The order of |
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.
I had that originally but JDT seems to allow having overlapping packages and that caused the exception to trigger. If you are fine with rejecting such code I will re-add the check.
Yes, I think we'll go with that first as it's an easy solution, and having overlapping packages seems to be entirely incompatible with the module system at runtime. So, we'll do it like that and... see what happens.
Otherwise, LGTM, thanks @I-Al-Istannen !
About this PR
This PR closes #4051 by always using the matching package with most contained types. This ensures we will skip "synthetic" packages in overlapping modules and fetch the package from the correct module.
Considerations
getContainedTypeCount
getter was added asCtPackage#getAllTypes
copies the full set just to callsize
on it. The getter does pollute theCtPackage
interface a bit though.Further Work
Cache packages in CtModule
(e1b82d3) commit the PR significantly increases runtime on codebases with modules. This happens as it callsgetPackageFromModule
on quite a few modules and that is a costly operation -- it iterates through the whole package chain each time:fr.inria.spoon.*
would walk down the chain in every module this application has, causing a lot of unnecessary work.The cache would need to be kept up-to-date though, which this PR doesn't implement as of now and might pose a challenge. Therefore I would trim off the commit and open a different PR for it after this one is merged.