Print short build time summary after build
This commit is contained in:
@@ -664,3 +664,5 @@ tasks.create("findShadowJarsInClasspath").doLast {
|
||||
project.checkConfig("testCompileClasspath")
|
||||
}
|
||||
}
|
||||
|
||||
BuildTimeReporter.configure(gradle)
|
||||
@@ -663,3 +663,5 @@ tasks.create("findShadowJarsInClasspath").doLast {
|
||||
project.checkConfig("testCompileClasspath")
|
||||
}
|
||||
}
|
||||
|
||||
BuildTimeReporter.configure(gradle)
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.execution.TaskExecutionListener
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.tasks.TaskState
|
||||
import java.util.HashMap
|
||||
|
||||
class BuildTimeReporter(
|
||||
private val kotlinCompileClass: Class<*>,
|
||||
private val javaCompileClass: Class<*>,
|
||||
private val jarClass: Class<*>,
|
||||
private val proguardClass: Class<*>
|
||||
) : TaskExecutionListener {
|
||||
companion object {
|
||||
fun configure(gradle: Gradle) {
|
||||
val rootProject = gradle.rootProject
|
||||
val logger = rootProject.logger
|
||||
val classloader = rootProject.buildscript.classLoader
|
||||
|
||||
fun findClass(name: String): Class<*>? =
|
||||
try {
|
||||
Class.forName(name, false, classloader)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
logger.warn("Could not find class '$name'. Build times won't be reported")
|
||||
null
|
||||
}
|
||||
|
||||
val reporter = BuildTimeReporter(
|
||||
kotlinCompileClass = findClass("org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile") ?: return,
|
||||
javaCompileClass = findClass("org.gradle.api.tasks.compile.JavaCompile") ?: return,
|
||||
jarClass = findClass("org.gradle.jvm.tasks.Jar") ?: return,
|
||||
proguardClass = findClass("proguard.gradle.ProGuardTask") ?: return
|
||||
)
|
||||
gradle.taskGraph.addTaskExecutionListener(reporter)
|
||||
gradle.buildFinished {
|
||||
reporter.report(logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum class TaskCategory {
|
||||
COMPILING_KOTLIN,
|
||||
COMPILING_JAVA,
|
||||
PROCESSING_JARS,
|
||||
UNCATEGORIZED;
|
||||
|
||||
private fun String.toTitleCase() =
|
||||
if (length <= 1) capitalize() else { get(0).toUpperCase() + substring(1).toLowerCase() }
|
||||
|
||||
fun description(): String =
|
||||
name.replace("_", " ").toTitleCase()
|
||||
}
|
||||
|
||||
private val taskStartTime = HashMap<Task, Long>()
|
||||
private val categoryTimeNs = HashMap<TaskCategory, Long>()
|
||||
private var totalTimeNs = 0L
|
||||
|
||||
@Synchronized
|
||||
override fun beforeExecute(task: Task) {
|
||||
taskStartTime[task] = System.nanoTime()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun afterExecute(task: Task, state: TaskState) {
|
||||
val startTimeNs = taskStartTime.remove(task) ?: return
|
||||
val endTimeNs = System.nanoTime()
|
||||
val timeNs = endTimeNs - startTimeNs
|
||||
totalTimeNs += timeNs
|
||||
val category = taskCategory(task)
|
||||
categoryTimeNs[category] = (categoryTimeNs[category] ?: 0L) + timeNs
|
||||
}
|
||||
|
||||
private fun taskCategory(task: Task): TaskCategory = when {
|
||||
kotlinCompileClass.isInstance(task) -> TaskCategory.COMPILING_KOTLIN
|
||||
javaCompileClass.isInstance(task) -> TaskCategory.COMPILING_JAVA
|
||||
jarClass.isInstance(task) ||
|
||||
proguardClass.isInstance(task) -> TaskCategory.PROCESSING_JARS
|
||||
else -> TaskCategory.UNCATEGORIZED
|
||||
}
|
||||
|
||||
private fun Double.asShortString() =
|
||||
String.format("%.2f", this)
|
||||
|
||||
@Synchronized
|
||||
private fun report(log: Logger) {
|
||||
val secondInNs = 1000_000_000
|
||||
val totalTimeSec = totalTimeNs.toDouble() / secondInNs
|
||||
if (totalTimeSec < 1) return
|
||||
|
||||
log.warn("Build time for tasks:")
|
||||
for (category in TaskCategory.values()) {
|
||||
val timeNs = categoryTimeNs[category] ?: 0L
|
||||
val timeSec = timeNs.toDouble() / secondInNs
|
||||
if (timeSec < 1) continue
|
||||
|
||||
val percent = timeSec / totalTimeSec * 100
|
||||
log.warn("${category.description()}: ${timeSec.asShortString()}s (${percent.asShortString()}% of total time)")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user