[Gradle] Implement very simple performance tracking for IdeDependencyResovlers
^KT-55289 Verification Pending
This commit is contained in:
committed by
Space Team
parent
7a89f4087a
commit
d6f855b225
+23
-10
@@ -17,10 +17,12 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver.Companion.re
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.*
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Companion.logger
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Companion.logger
|
||||||
import org.jetbrains.kotlin.tooling.core.Extras
|
import org.jetbrains.kotlin.tooling.core.Extras
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.measureTimeMillisWithResult
|
||||||
|
|
||||||
|
|
||||||
internal class IdeMultiplatformImportImpl(
|
internal class IdeMultiplatformImportImpl(
|
||||||
private val extension: KotlinProjectExtension
|
private val extension: KotlinProjectExtension,
|
||||||
|
val statistics: IdeMultiplatformImportStatistics = IdeMultiplatformImportStatistics()
|
||||||
) : IdeMultiplatformImport {
|
) : IdeMultiplatformImport {
|
||||||
|
|
||||||
override fun resolveDependencies(sourceSetName: String): Set<IdeaKotlinDependency> {
|
override fun resolveDependencies(sourceSetName: String): Set<IdeaKotlinDependency> {
|
||||||
@@ -59,7 +61,7 @@ internal class IdeMultiplatformImportImpl(
|
|||||||
level: DependencyResolutionLevel
|
level: DependencyResolutionLevel
|
||||||
) {
|
) {
|
||||||
registeredDependencyResolvers.add(
|
registeredDependencyResolvers.add(
|
||||||
RegisteredDependencyResolver(resolver, constraint, phase, level)
|
RegisteredDependencyResolver(statistics, resolver, constraint, phase, level)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (resolver is IdeDependencyResolver.WithBuildDependencies) {
|
if (resolver is IdeDependencyResolver.WithBuildDependencies) {
|
||||||
@@ -159,28 +161,40 @@ internal class IdeMultiplatformImportImpl(
|
|||||||
val constraint: SourceSetConstraint,
|
val constraint: SourceSetConstraint,
|
||||||
)
|
)
|
||||||
|
|
||||||
private class RegisteredDependencyResolver(
|
private data class RegisteredDependencyResolver(
|
||||||
|
private val statistics: IdeMultiplatformImportStatistics,
|
||||||
private val resolver: IdeDependencyResolver,
|
private val resolver: IdeDependencyResolver,
|
||||||
val constraint: SourceSetConstraint,
|
val constraint: SourceSetConstraint,
|
||||||
val phase: DependencyResolutionPhase,
|
val phase: DependencyResolutionPhase,
|
||||||
val level: DependencyResolutionLevel,
|
val level: DependencyResolutionLevel,
|
||||||
) : IdeDependencyResolver {
|
) : IdeDependencyResolver {
|
||||||
|
|
||||||
|
private class TimeMeasuredResult(val timeInMillis: Long, val dependencies: Set<IdeaKotlinDependency>)
|
||||||
|
|
||||||
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||||
return runCatching { resolver.resolve(sourceSet) }
|
return runCatching { resolveTimed(sourceSet) }
|
||||||
.onFailure { error -> reportError(sourceSet, error) }
|
.onFailure { error -> reportError(sourceSet, error) }
|
||||||
.onSuccess { dependencies -> reportSuccess(sourceSet, dependencies) }
|
.onSuccess { result -> reportSuccess(sourceSet, result) }
|
||||||
.onSuccess { dependencies -> attachResolvedByExtra(dependencies) }
|
.onSuccess { result -> attachResolvedByExtra(result.dependencies) }
|
||||||
.getOrNull().orEmpty()
|
.getOrNull()?.dependencies.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveTimed(sourceSet: KotlinSourceSet): TimeMeasuredResult {
|
||||||
|
val (time, result) = measureTimeMillisWithResult { resolver.resolve(sourceSet) }
|
||||||
|
statistics.addExecutionTime(resolver::class.java, time)
|
||||||
|
return TimeMeasuredResult(time, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportError(sourceSet: KotlinSourceSet, error: Throwable) {
|
private fun reportError(sourceSet: KotlinSourceSet, error: Throwable) {
|
||||||
logger.error("e: ${resolver::class.java.name} failed on ${IdeaKotlinSourceCoordinates(sourceSet)}", error)
|
logger.error("e: ${resolver::class.java.name} failed on ${IdeaKotlinSourceCoordinates(sourceSet)}", error)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportSuccess(sourceSet: KotlinSourceSet, dependencies: Set<IdeaKotlinDependency>) {
|
private fun reportSuccess(sourceSet: KotlinSourceSet, result: TimeMeasuredResult) {
|
||||||
if (!logger.isDebugEnabled) return
|
if (!logger.isDebugEnabled) return
|
||||||
logger.debug("${resolver::class.java.name} resolved on ${IdeaKotlinSourceCoordinates(sourceSet)}: $dependencies")
|
logger.debug(
|
||||||
|
"${resolver::class.java.name} resolved on ${IdeaKotlinSourceCoordinates(sourceSet)}: " +
|
||||||
|
"${result.dependencies} (${result.timeInMillis} ms)"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun attachResolvedByExtra(dependencies: Iterable<IdeaKotlinDependency>) {
|
private fun attachResolvedByExtra(dependencies: Iterable<IdeaKotlinDependency>) {
|
||||||
@@ -189,5 +203,4 @@ internal class IdeMultiplatformImportImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.ide
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation to track dependency resolution bottlenecks.
|
||||||
|
* This will later be replaced by properly tracing ide import.
|
||||||
|
*/
|
||||||
|
internal class IdeMultiplatformImportStatistics {
|
||||||
|
|
||||||
|
private val times = mutableMapOf<Class<*>, Long>()
|
||||||
|
|
||||||
|
fun addExecutionTime(clazz: Class<*>, timeInMillis: Long) {
|
||||||
|
times[clazz] = times.getOrDefault(clazz, 0) + timeInMillis
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getExecutionTimes(): Map<Class<*>, Long> {
|
||||||
|
return times.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
times.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -13,6 +13,7 @@ import org.gradle.api.tasks.TaskProvider
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependencyCoordinates
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependencyCoordinates
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.appendLine
|
||||||
import org.jetbrains.kotlin.gradle.utils.notCompatibleWithConfigurationCacheCompat
|
import org.jetbrains.kotlin.gradle.utils.notCompatibleWithConfigurationCacheCompat
|
||||||
import org.jetbrains.kotlin.tooling.core.Extras
|
import org.jetbrains.kotlin.tooling.core.Extras
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -57,6 +58,15 @@ internal open class IdeResolveDependenciesTask : DefaultTask() {
|
|||||||
protoOutput.writeBytes(proto)
|
protoOutput.writeBytes(proto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(project.kotlinIdeMultiplatformImport as? IdeMultiplatformImportImpl)?.statistics?.let { statistics ->
|
||||||
|
val timeStatisticsFile = outputDirectory.resolve("times.txt")
|
||||||
|
timeStatisticsFile.writeText(buildString {
|
||||||
|
statistics.getExecutionTimes().forEach { (clazz, time) ->
|
||||||
|
appendLine("${clazz.name} $time.ms")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object IdeDependencyResolverAdapter : JsonSerializer<IdeDependencyResolver> {
|
private object IdeDependencyResolverAdapter : JsonSerializer<IdeDependencyResolver> {
|
||||||
|
|||||||
Reference in New Issue
Block a user