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

Make using of the compiler single-thread #3151 #3202

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions plugins/base/src/main/kotlin/generation/SingleModuleGeneration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

package org.jetbrains.dokka.base.generation

import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.runBlocking
import org.jetbrains.dokka.CoreExtensions
import org.jetbrains.dokka.DokkaConfiguration
Expand Down Expand Up @@ -61,11 +63,18 @@ public class SingleModuleGeneration(private val context: DokkaContext) : Generat

override val generationName: String = "documentation for ${context.configuration.moduleName}"

public fun createDocumentationModels(): List<DModule> = runBlocking(Dispatchers.Default) {
context.configuration.sourceSets.parallelMap { sourceSet -> translateSources(sourceSet, context) }.flatten()
.also { modules -> if (modules.isEmpty()) exitGenerationGracefully("Nothing to document") }
/**
* Implementation note: it runs in a separated single thread due to existing support of coroutines (see #2936)
*/
@OptIn(DelicateCoroutinesApi::class)
public fun createDocumentationModels(): List<DModule> = newSingleThreadContext("Generating documentable model").use { coroutineContext -> // see https://github.com/Kotlin/dokka/issues/3151
runBlocking(coroutineContext) {
context.configuration.sourceSets.parallelMap { sourceSet -> translateSources(sourceSet, context) }.flatten()
.also { modules -> if (modules.isEmpty()) exitGenerationGracefully("Nothing to document") }
}
}
Comment on lines +66 to 75
Copy link
Member

Choose a reason for hiding this comment

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

There's a considerable chance it can lead to noticeably worse performance in projects with K1, and it might be especially evident with the CLI runner. Maybe you had time to do a few test runs to compare before and after?

It breaks the abstraction, but what do you think about using this single-threaded implementation for K2 only? Just to avoid raising too many questions for now with nothing to offer

Copy link
Member

Choose a reason for hiding this comment

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

Update on this question after some internal discussions:

Vadim did some benchmarking of the CLI runner to see if this has any impact on performance, and it looks like the documentable model takes 20% more time to be generated, but it's just a fraction of the overall time Dokka takes to generate documentation, so it's not really visible if you look at the whole run and not just an individual step.

Since we plan to get rid of coroutines either way, it's an acceptable solution for now.



public fun transformDocumentationModelBeforeMerge(modulesFromPlatforms: List<DModule>): List<DModule> {
return context.plugin<DokkaBase>()
.query { preMergeDocumentableTransformer }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ package org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.translator
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.util.PsiLiteralUtil.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.*
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin
import org.jetbrains.dokka.analysis.java.parsers.JavadocParser
Expand Down Expand Up @@ -124,6 +121,10 @@ internal class DefaultDescriptorToDocumentableTranslator(
}
}

/**
* Implementation note: it runs in a separated single thread due to existing support of coroutines (see #2936)
*/
@OptIn(DelicateCoroutinesApi::class)
override fun translateClassDescriptor(descriptor: ClassDescriptor, sourceSet: DokkaSourceSet): DClasslike {
val driInfo = DRI.from(descriptor.parents.first()).withEmptyInfo()

Expand All @@ -132,9 +133,11 @@ internal class DefaultDescriptorToDocumentableTranslator(
docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder
)

return runBlocking(Dispatchers.Default) {
DokkaDescriptorVisitor(sourceSet, kdocFinder, kotlinAnalysis[sourceSet], context.logger, javadocParser)
.visitClassDescriptor(descriptor, driInfo)
return newSingleThreadContext("Generating documentable model of classlike").use { coroutineContext -> // see https://github.com/Kotlin/dokka/issues/3151
runBlocking(coroutineContext) {
DokkaDescriptorVisitor(sourceSet, kdocFinder, kotlinAnalysis[sourceSet], context.logger, javadocParser)
.visitClassDescriptor(descriptor, driInfo)
}
}
}
}
Expand Down