-
Notifications
You must be signed in to change notification settings - Fork 34
Description
I was looking at this code in server.jl, where it loads the packages one by one, and then every time does a bunch of work over the whole package environment:
Lines 95 to 100 in 3162b6a
| for (i, uuid) in enumerate(packages_to_load) | |
| load_package(ctx, uuid, conn, LoadingBay, round(Int, 100*(i - 1)/length(packages_to_load))) | |
| # XXX: The following *may* duplicate some work, but we want to make sure that interrupts of | |
| # the SymbolServer process don't invalidate *all* work done (which would happen when only | |
| # writing the cache files out after all packages are loaded) |
The comment alludes to how this may duplicate some work. It is a bit of an understatement. I was testing with indexing an environment containing only Plots and its dependencies, and I tried moving the end of the loop on line 95 up to line 97, so we do all the load_package calls up front.
This made the total indexing time go from 109.1 seconds to 12.2 seconds. Almost a 10X improvement from this one change!
In general, I think the perf of SymbolServer.jl has more low-hanging fruit, such as indexing and loading on-disk stores in parallel using multiple threads. I feel that the current painful performance has led to workarounds like the cloud indexing system, which I've never seen before in any other LSP ecosystem and which I really wish didn't exist. (Even more philosophically, I wonder why gobs of symbols need to be indexed and stored in memory up-front at all? Doesn't Julia have the introspection machinery to enable LanguageServer.jl to look up (and cache as needed) the necessary symbols as it runs?)
In my usage at least, SymbolServer.jl is the main contributor to slow startup times and high CPU/memory usage when using LanguageServer.jl. I think a leaner and meaner SymbolServer.jl would make life much nicer for LanguageServer.jl users.
CC @mkitti since you were so helpful with the last perf issue I reported. Also CC @davidanthoff.