perf: optimize Java Language Server startup time - #4514
angelozerr wants to merge 1 commit into
Conversation
c29af18 to
0a07746
Compare
|
Seems like a good idea and a really helpful improvement. Reading through your description and the code, wouldn't this make more sense for these changes to be made in the I'm going to try it out on Windows to see if I notice the performance improvement there. |
|
I don't seem to be running into the slowdown like you mention. The activating step takes around 4 seconds on my Windows computer, before and after this change. I have 7 JDKs installed. |
|
I misunderstood your fix at first, though, I think this is a good idea. |
|
OH I don't have an embedded JRE, that's probably why |
|
It seems like |
datho7561
left a comment
There was a problem hiding this comment.
I think the other fixes seem like good ideas, but from my understanding, the release file optimization should already be performed by jdk-utils so it's redundant to include it here.
I don't notice a significant improvement in startup time, both before and after this change takes around 4 seconds for me.
The timing which is improved is when vscode starts and |
I have tried to use 0.7.0 (we use 0.6.0) of jdk-utils whic have this fix and for some reason it is slower. This PR uses: and is fast. jdk-utils uses:
and it is slow. Perhaps this problem exists only when vscode-java is started in debug mode. Is it possible to keep this code in vscode-java and I will create a PR in jdk-utils. |
|
Just to confirm, you were seeing a significant difference in the performance? When I added timing and timed the two solutions, both this PR and the main branch took around 300 ms. |
|
@datho7561 can you check on windows? |
I've been testing on Windows. I have 7 JDKs installed (I installed a few to check if that's the issue). The startup time before and after this change is ~300 ms.
In the case that the release file is corrupted, both vscode-java and jdk-utils will attempt to read it, which will waste time. It's generally considered bad practice to use the synchronous version of the file operations, since NodeJS can switch to a different task while the file is being read if the asynchronous |
Reduce startup time from ~72s to ~49ms by eliminating unnecessary subprocess calls, system scans, and disk I/O on the critical path: - Read JDK release file instead of spawning java -version subprocess in getMajorVersion() (was ~33s per call) - Skip listJdks() system scan in resolveRequirements when toolingJre is valid - defer JDK discovery after server startup via didChangeConfiguration notification (was ~16s) - Defer addAutoDetectedJdks in getJavaConfig until after server start by adding skipAutoDetection parameter - Use context.extension.packageJSON.version instead of reading and parsing package.json from disk in getVersion() (3 calls at startup) Signed-off-by: azerr <azerr@redhat.com>
0a07746 to
39f218f
Compare
I have removed my code and use jdk-utils. |

Summary
Optimize Java Language Server startup time by eliminating expensive subprocess calls, unnecessary system scans, and redundant disk I/O on the critical startup path.
Before: ~72s | After: ~49ms (99.93% reduction)
Changes
getMajorVersion()readreleasefile instead of spawningjava -version: Replacejdk-utilssubprocess call with a synchronous read of the JDK'sreleasefile to extractJAVA_VERSION. Saves ~33s (2 calls at startup).listJdks()skip system scan when unnecessary: Only calllistJdks()if no valid embedded JRE is found. When toolingJre is available, defer JDK auto-detection to after server startup viadidChangeConfiguration.getJavaConfig()defer JDK auto-detection after startup: AddskipAutoDetectionparameter to avoid callinglistJdks()before server start. Send full configuration (with auto-detected JDKs) afterstandardClient.start().getVersion()usecontext.extension.packageJSONinstead of readingpackage.jsonfrom disk: Avoidfs.readFileSync+JSON.parseon every call (3 calls at startup).Measurements (embedded JRE present, no
java.homeconfigured)getMajorVersion(toolingJre)listJdksresolveRequirementstotalTest plan
java.homeconfigured)java.homesettingjava -versionfallback works ifreleasefile is missing/malformed