Skip to content
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

[performance] PackageFragmentRoot.getRawClasspathEntry() has bad impact on startup performance #3468

Open
laeubi opened this issue Dec 17, 2024 · 7 comments
Assignees

Comments

@laeubi
Copy link
Contributor

laeubi commented Dec 17, 2024

While looking at a problem here I noticed that PackageFragmentRoot.getRawClasspathEntry() has a very bad impact on startup performance because it calls project.getResolvedClasspath()

project.getResolvedClasspath(); // force the reverse rawEntry cache to be populated

this leads to a resolve operation of all classpath containers (that actually should happen in a background thread!) in the main UI thread whenever one has an open Java Editor + Package Explorer open. This even blocks the whole UI startup of eclipse.

This is sadly not the only place where this could happen... but the other places are more UI related.

@srikanth-sankaran
Copy link
Contributor

Jay, thanks for taking a look

@laeubi
Copy link
Contributor Author

laeubi commented Dec 17, 2024

Especially calling "Raw" ClasspathEntry would indicate for me it is actually not resolved as there is also

public IClasspathEntry getResolvedClasspathEntry() throws JavaModelException {

@jarthana
Copy link
Member

jarthana commented Jan 7, 2025

Classpath containers are designed to be lazily initialized, so removing getResolvedClasspath shouldn't make a difference. Anyway, let me run some tests/experiments and get back.

@laeubi
Copy link
Contributor Author

laeubi commented Jan 7, 2025

Classpath containers are designed to be lazily initialized

Can you give an example? I just take a look into subclasses of ClasspathContainerInitializer that I found in JDT+PDE an none of them are lazy all of them sooner or later calling JavaCore.setClasspathContainer in the calling thread of org.eclipse.jdt.core.ClasspathContainerInitializer.initialize(IPath, IJavaProject)

@jarthana
Copy link
Member

jarthana commented Jan 7, 2025

Classpath containers are designed to be lazily initialized

Can you give an example? I just take a look into subclasses of ClasspathContainerInitializer that I found in JDT+PDE an none of them are lazy all of them sooner or later calling JavaCore.setClasspathContainer in the calling thread of org.eclipse.jdt.core.ClasspathContainerInitializer.initialize(IPath, IJavaProject)

OK, my last statement wasn't accurate. What I had in mind was two things: the resolution of the classpath entries itself. getResolvedClasspath() resolves the classpath on demand and no need for it to be invoked when getRawClasspathEntry, which you have called out already. Second, the initialization of the containers themselves is done in a background thread.

BTW, I just ran all model tests after removing the code in question and didn't observe any difference in behavior. All tests passed and took about the same amount of time.

@laeubi
Copy link
Contributor Author

laeubi commented Jan 7, 2025

Second, the initialization of the containers themselves is done in a background thread.

Only if JDT.UI can start before anyone calls a method that enforce an init of the containers.

@laeubi
Copy link
Contributor Author

laeubi commented Jan 7, 2025

By the way if anyone wants to debug it simply do the following:

  1. Put a breakpoint in PackageFragmentRoot#getRawClasspathEntry
  2. start a new ide instance and open a java source editor from a project (close any other editors) a
  3. restart the ide in debug mode and see the method is hit in the main thread, no UI is displayed until the breakpoint is run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants