Metrics reporting utils
This commit is contained in:
committed by
Alexander Likhachev
parent
97a09680d5
commit
5bde6457b1
@@ -16,4 +16,21 @@ interface ICReporter {
|
|||||||
fun reportMarkDirtyClass(affectedFiles: Iterable<File>, classFqName: String)
|
fun reportMarkDirtyClass(affectedFiles: Iterable<File>, classFqName: String)
|
||||||
fun reportMarkDirtyMember(affectedFiles: Iterable<File>, scope: String, name: String)
|
fun reportMarkDirtyMember(affectedFiles: Iterable<File>, scope: String, name: String)
|
||||||
fun reportMarkDirty(affectedFiles: Iterable<File>, reason: String)
|
fun reportMarkDirty(affectedFiles: Iterable<File>, reason: String)
|
||||||
|
|
||||||
|
fun startMeasure(metric: String, startNs: Long)
|
||||||
|
fun endMeasure(metric: String, endNs: Long)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> ICReporter?.measure(metric: String, fn: () -> T): T {
|
||||||
|
if (this == null) return fn()
|
||||||
|
|
||||||
|
val start = System.nanoTime()
|
||||||
|
startMeasure(metric, start)
|
||||||
|
|
||||||
|
try {
|
||||||
|
return fn()
|
||||||
|
} finally {
|
||||||
|
val end = System.nanoTime()
|
||||||
|
endMeasure(metric, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,4 +33,10 @@ abstract class ICReporterBase(private val pathsBase: File? = null) : ICReporter
|
|||||||
|
|
||||||
protected fun File.relativeOrCanonical(): File =
|
protected fun File.relativeOrCanonical(): File =
|
||||||
pathsBase?.let { relativeToOrNull(it) } ?: canonicalFile
|
pathsBase?.let { relativeToOrNull(it) } ?: canonicalFile
|
||||||
|
|
||||||
|
override fun startMeasure(metric: String, startNs: Long) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun endMeasure(metric: String, endNs: Long) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,15 +10,21 @@ import org.jetbrains.kotlin.daemon.common.CompilationResultCategory
|
|||||||
import org.jetbrains.kotlin.daemon.common.CompilationResults
|
import org.jetbrains.kotlin.daemon.common.CompilationResults
|
||||||
import org.jetbrains.kotlin.incremental.ICReporterBase
|
import org.jetbrains.kotlin.incremental.ICReporterBase
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.HashMap
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
internal class BuildReportICReporter(
|
internal class BuildReportICReporter(
|
||||||
private val compilationResults: CompilationResults,
|
private val compilationResults: CompilationResults,
|
||||||
rootDir: File,
|
rootDir: File,
|
||||||
private val isVerbose: Boolean = false
|
private val isVerbose: Boolean = false,
|
||||||
|
// todo: default value
|
||||||
|
// todo: sync BuildReportICReporterAsync
|
||||||
|
private val reportMetrics: Boolean = true
|
||||||
) : ICReporterBase(rootDir), RemoteICReporter {
|
) : ICReporterBase(rootDir), RemoteICReporter {
|
||||||
private val icLogLines = arrayListOf<String>()
|
private val icLogLines = arrayListOf<String>()
|
||||||
private val recompilationReason = HashMap<File, String>()
|
private val recompilationReason = HashMap<File, String>()
|
||||||
|
private val rootMetric = Metric("<root>", 0)
|
||||||
|
private val metrics = ArrayDeque<Metric>().apply { add(rootMetric) }
|
||||||
|
|
||||||
override fun report(message: () -> String) {
|
override fun report(message: () -> String) {
|
||||||
icLogLines.add(message())
|
icLogLines.add(message())
|
||||||
@@ -30,6 +36,30 @@ internal class BuildReportICReporter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun startMeasure(metric: String, startNs: Long) {
|
||||||
|
if (!reportMetrics) return
|
||||||
|
|
||||||
|
val newMetric = Metric(metric, startNs)
|
||||||
|
if (metrics.isNotEmpty()) {
|
||||||
|
metrics.peekLast().children.add(newMetric)
|
||||||
|
}
|
||||||
|
metrics.addLast(newMetric)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun endMeasure(metric: String, endNs: Long) {
|
||||||
|
if (!reportMetrics) return
|
||||||
|
|
||||||
|
while (metrics.isNotEmpty()) {
|
||||||
|
val lastMetric = metrics.peekLast()
|
||||||
|
if (lastMetric.name == metric) {
|
||||||
|
lastMetric.endNs = endNs
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
metrics.removeLast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection<File>, exitCode: ExitCode) {
|
override fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection<File>, exitCode: ExitCode) {
|
||||||
if (!incremental) return
|
if (!incremental) return
|
||||||
|
|
||||||
@@ -46,6 +76,25 @@ internal class BuildReportICReporter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun flush() {
|
override fun flush() {
|
||||||
|
if (reportMetrics) {
|
||||||
|
icLogLines.add("Performance metrics:")
|
||||||
|
reportMetric(rootMetric)
|
||||||
|
}
|
||||||
|
|
||||||
compilationResults.add(CompilationResultCategory.BUILD_REPORT_LINES.code, icLogLines)
|
compilationResults.add(CompilationResultCategory.BUILD_REPORT_LINES.code, icLogLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun reportMetric(metric: Metric, level: Int = 0) {
|
||||||
|
if (level > 0) {
|
||||||
|
val timeMs = metric.endNs?.let { (it - metric.startNs) / 1_000_000L }
|
||||||
|
icLogLines.add(" ".repeat(level) + "{perf_metric:${metric.name}} ${timeMs ?: "<unknown>"} ms")
|
||||||
|
}
|
||||||
|
|
||||||
|
metric.children.forEach { reportMetric(it, level + 1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Metric(val name: String, val startNs: Long) {
|
||||||
|
var endNs: Long? = null
|
||||||
|
val children = ArrayList<Metric>()
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,14 @@ internal class CompositeICReporter(private val reporters: Iterable<RemoteICRepor
|
|||||||
reporters.forEach { it.reportMarkDirty(affectedFiles, reason) }
|
reporters.forEach { it.reportMarkDirty(affectedFiles, reason) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun startMeasure(metric: String, startNs: Long) {
|
||||||
|
reporters.forEach { it.startMeasure(metric, startNs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun endMeasure(metric: String, endNs: Long) {
|
||||||
|
reporters.forEach { it.endMeasure(metric, endNs) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun flush() {
|
override fun flush() {
|
||||||
reporters.forEach { it.flush() }
|
reporters.forEach { it.flush() }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user