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

Remove various caches from JvmDependenciesIndexImpl #2366

Closed
wants to merge 2 commits into from

Conversation

IgnatBeresnev
Copy link
Member

Removed various caches and did some dokkaHtmlMultiModule benchmarking on kotlinx-coroutines.

I benchmarked 4 times: baseline (current master) + once for each removed cache (#1, #2 and #3, will outline them by comments) to see the impact of each removed cache.

The results (html link) show that there's no significant build time degradation, but the benchmarks are not as ideal as they could be:

  1. Now that I understand how these caches work, perhaps kotlinx-coroutines wasn't the best project to benchmark on -- it doesn't have that many dependencies and roots, so the cache is relatively small in size. I wonder if the results will be any different on a large scale enterprise project
  2. As far as I understand, the caches were introduced to reduce load on IO, so supposedly we'll see the biggest difference on slow aged HDDs, whereas the benchmarks were performed on a pristine new gen SSD with a lot of free memory, so the files were probably cached as well.

Alternatively, it's possible to add some basic thread safety to the current solution by synchronizing on individual Cache objects when working with them, but because there's a section where two caches need to be locked consecutively, I can come up with a hypothetical concurrent scenario in which a deadlock happens (whether it could actually happen is a good question, need more time to investigate).

P.S., turns out, JvmDependenciesIndexImpl was copy-pasted from the kotlin repo (it also has caches), which makes it a little scary to remove (hopefully it was introduced to kotlin based on some testing). I was unable to find the PR or any attached issue to introducing the caches, so not sure what the motivation was behind it, and its primary contributor does not work at JB anymore, so I can't ask directly.


// root "Cache" object corresponds to DefaultPackage which exists in every root. Roots with non-default fqname are also listed here but
// they will be ignored on requests with invalid fqname prefix.
private val rootCache: Cache by lazy {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Main cache №1, the one we've been having problems with. It's also nested.

Basically maps packages to an index inside roots (separate field at the top) to reduce lookup time (no need to iterate all roots, just the roots of requested packages). Making this implementation (as is) thread safe could be problematic, more info in the PR description


// holds the request and the result last time we searched for class
// helps improve several scenarios, LazyJavaResolverContext.findClassInJava being the most important
private var lastClassSearch: Pair<FindClassRequest, SearchResult>? = null
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache №2. There are cache hits, actually more than I thought, so this could be useful. Could be made thread safe with volatile without much problem. No reports of it misbehaving, although there could've been invisible concurrency issues (since there's no synchronization)

Comment on lines -67 to -69
private val packageCache: Array<out MutableMap<String, VirtualFile?>> by lazy {
Array(roots.size) { THashMap<String, VirtualFile?>() }
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache №3. Already synchronized on, so there shouldn't have been any problems with it. Seems to be the most important one as it saves most of the heavy lifting (stores the result of findChildPackage). I think this can be safely reverted

@IgnatBeresnev IgnatBeresnev linked an issue Feb 16, 2022 that may be closed by this pull request
@zarechenskiy
Copy link
Member

Speaking about original motivation: this index was copied to fix #1599, there was a problem with the Trove library

@IgnatBeresnev
Copy link
Member Author

Stale. Will re-open if this is needed for tests again.

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

Successfully merging this pull request may close these issues.

Unstable document generation with dokka cli
3 participants