diff --git a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporter.kt b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporter.kt index 65555b8c0bd..5c5142905f2 100644 --- a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporter.kt +++ b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporter.kt @@ -6,26 +6,24 @@ package org.jetbrains.kotlin.build.report.metrics interface BuildMetricsReporter { - fun startMeasure(time: BuildTime, startNs: Long) - fun endMeasure(time: BuildTime, endNs: Long) - fun addTimeMetric(time: BuildTime, durationMs: Long) + fun startMeasure(time: BuildTime) + fun endMeasure(time: BuildTime) + fun addTimeMetricNs(time: BuildTime, durationNs: Long) + fun addTimeMetricMs(time: BuildTime, durationMs: Long) = addTimeMetricNs(time, durationMs * 1_000_000) fun addMetric(metric: BuildPerformanceMetric, value: Long) fun addAttribute(attribute: BuildAttribute) fun getMetrics(): BuildMetrics - fun addMetrics(metrics: BuildMetrics?) + fun addMetrics(metrics: BuildMetrics) } inline fun BuildMetricsReporter.measure(time: BuildTime, fn: () -> T): T { - val start = System.nanoTime() - startMeasure(time, start) - + startMeasure(time) try { return fn() } finally { - val end = System.nanoTime() - endMeasure(time, end) + endMeasure(time) } } \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt index 9ed25193f22..f7f2dcf5276 100644 --- a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt +++ b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt @@ -17,21 +17,21 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable { private val myBuildMetrics = BuildPerformanceMetrics() private val myBuildAttributes = BuildAttributes() - override fun startMeasure(time: BuildTime, startNs: Long) { + override fun startMeasure(time: BuildTime) { if (time in myBuildTimeStartNs) { error("$time was restarted before it finished") } - myBuildTimeStartNs[time] = startNs + myBuildTimeStartNs[time] = System.nanoTime() } - override fun endMeasure(time: BuildTime, endNs: Long) { + override fun endMeasure(time: BuildTime) { val startNs = myBuildTimeStartNs.remove(time) ?: error("$time finished before it started") - val durationMs = (endNs - startNs) / 1_000_000 - myBuildTimes.add(time, durationMs) + val durationNs = System.nanoTime() - startNs + myBuildTimes.addTimeNs(time, durationNs) } - override fun addTimeMetric(time: BuildTime, durationMs: Long) { - myBuildTimes.add(time, durationMs) + override fun addTimeMetricNs(time: BuildTime, durationNs: Long) { + myBuildTimes.addTimeNs(time, durationNs) } override fun addMetric(metric: BuildPerformanceMetric, value: Long) { @@ -49,9 +49,7 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable { buildAttributes = myBuildAttributes ) - override fun addMetrics(metrics: BuildMetrics?) { - if (metrics == null) return - + override fun addMetrics(metrics: BuildMetrics) { myBuildAttributes.addAll(metrics.buildAttributes) myBuildTimes.addAll(metrics.buildTimes) myBuildMetrics.addAll(metrics.buildPerformanceMetrics) diff --git a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildTimes.kt b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildTimes.kt index 9de86fd360c..5b5368d7808 100644 --- a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildTimes.kt +++ b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildTimes.kt @@ -9,19 +9,23 @@ import java.io.Serializable import java.util.* class BuildTimes : Serializable { - private val myBuildTimes = EnumMap(BuildTime::class.java) + private val buildTimesNs = EnumMap(BuildTime::class.java) fun addAll(other: BuildTimes) { - for ((bt, timeMs) in other.myBuildTimes) { - add(bt, timeMs) + for ((buildTime, timeNs) in other.buildTimesNs) { + addTimeNs(buildTime, timeNs) } } - fun add(buildTime: BuildTime, timeMs: Long) { - myBuildTimes[buildTime] = myBuildTimes.getOrDefault(buildTime, 0) + timeMs + fun addTimeNs(buildTime: BuildTime, timeNs: Long) { + buildTimesNs[buildTime] = buildTimesNs.getOrDefault(buildTime, 0) + timeNs } - fun asMap(): Map = myBuildTimes + fun addTimeMs(buildTime: BuildTime, timeMs: Long) = addTimeNs(buildTime, timeMs * 1_000_000) + + fun asMapNs(): Map = buildTimesNs + + fun asMapMs(): Map = buildTimesNs.mapValues { it.value / 1_000_000 } companion object { const val serialVersionUID = 0L diff --git a/build-common/src/org/jetbrains/kotlin/build/report/metrics/DoNothingBuildMetricsReporter.kt b/build-common/src/org/jetbrains/kotlin/build/report/metrics/DoNothingBuildMetricsReporter.kt index 5e0d76a3f33..6764c1f0a9a 100644 --- a/build-common/src/org/jetbrains/kotlin/build/report/metrics/DoNothingBuildMetricsReporter.kt +++ b/build-common/src/org/jetbrains/kotlin/build/report/metrics/DoNothingBuildMetricsReporter.kt @@ -6,13 +6,13 @@ package org.jetbrains.kotlin.build.report.metrics object DoNothingBuildMetricsReporter : BuildMetricsReporter { - override fun startMeasure(time: BuildTime, startNs: Long) { + override fun startMeasure(time: BuildTime) { } - override fun endMeasure(time: BuildTime, endNs: Long) { + override fun endMeasure(time: BuildTime) { } - override fun addTimeMetric(time: BuildTime, durationMs: Long) { + override fun addTimeMetricNs(time: BuildTime, durationNs: Long) { } override fun addMetric(metric: BuildPerformanceMetric, value: Long) { @@ -28,5 +28,5 @@ object DoNothingBuildMetricsReporter : BuildMetricsReporter { BuildAttributes() ) - override fun addMetrics(metrics: BuildMetrics?) {} + override fun addMetrics(metrics: BuildMetrics) {} } \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index 6f591ca4f7c..6a51b9f446c 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -513,9 +513,9 @@ abstract class IncrementalCompilerRunner< protected fun reportPerformanceData(defaultPerformanceManager: CommonCompilerPerformanceManager) { defaultPerformanceManager.getMeasurementResults().forEach { when (it) { - is CompilerInitializationMeasurement -> reporter.addTimeMetric(BuildTime.COMPILER_INITIALIZATION, it.milliseconds) - is CodeAnalysisMeasurement -> reporter.addTimeMetric(BuildTime.CODE_ANALYSIS, it.milliseconds) - is CodeGenerationMeasurement -> reporter.addTimeMetric(BuildTime.CODE_GENERATION, it.milliseconds) + is CompilerInitializationMeasurement -> reporter.addTimeMetricMs(BuildTime.COMPILER_INITIALIZATION, it.milliseconds) + is CodeAnalysisMeasurement -> reporter.addTimeMetricMs(BuildTime.CODE_ANALYSIS, it.milliseconds) + is CodeGenerationMeasurement -> reporter.addTimeMetricMs(BuildTime.CODE_GENERATION, it.milliseconds) } } } diff --git a/libraries/tools/kotlin-gradle-build-metrics/src/org/jetbrains/kotlin/gradle/internal/build/metrics/GradleBuildMetricsData.kt b/libraries/tools/kotlin-gradle-build-metrics/src/org/jetbrains/kotlin/gradle/internal/build/metrics/GradleBuildMetricsData.kt index e28af47f9cb..54be62bfa3a 100644 --- a/libraries/tools/kotlin-gradle-build-metrics/src/org/jetbrains/kotlin/gradle/internal/build/metrics/GradleBuildMetricsData.kt +++ b/libraries/tools/kotlin-gradle-build-metrics/src/org/jetbrains/kotlin/gradle/internal/build/metrics/GradleBuildMetricsData.kt @@ -20,7 +20,7 @@ class GradleBuildMetricsData : Serializable { data class TaskData( val path: String, val typeFqName: String, - val timeMetrics: Map, + val buildTimesMs: Map, val performanceMetrics: Map, val buildAttributes: Map, val didWork: Boolean diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilationResults.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilationResults.kt index b7fc42d8b4f..1dc7cac2b9a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilationResults.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilationResults.kt @@ -3,11 +3,7 @@ package org.jetbrains.kotlin.compilerRunner import org.jetbrains.kotlin.build.report.metrics.BuildMetrics import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric -import org.jetbrains.kotlin.daemon.common.CompilationResultCategory -import org.jetbrains.kotlin.daemon.common.CompilationResults -import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface -import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT -import org.jetbrains.kotlin.daemon.common.CompileIterationResult +import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.utils.pathsAsStringRelativeTo import java.io.File @@ -52,7 +48,7 @@ internal class GradleCompilationResults( (value as? List)?.let { icLogLines = it } } CompilationResultCategory.BUILD_METRICS.code -> { - buildMetricsReporter.addMetrics(value as? BuildMetrics) + (value as? BuildMetrics)?.let { buildMetricsReporter.addMetrics(it) } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index 5c826382459..831b46345a2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt @@ -18,9 +18,7 @@ import org.jetbrains.kotlin.gradle.logging.* import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.report.* -import org.jetbrains.kotlin.gradle.report.TaskExecutionInfo import org.jetbrains.kotlin.gradle.report.TaskExecutionProperties.ABI_SNAPSHOT -import org.jetbrains.kotlin.gradle.report.TaskExecutionResult import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError @@ -35,7 +33,6 @@ import java.util.* import java.util.concurrent.Callable import java.util.concurrent.Executors import javax.inject.Inject -import kotlin.collections.ArrayList internal class ProjectFilesForCompilation( val projectRootFile: File, @@ -324,7 +321,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( metrics.addAttribute(BuildAttribute.IN_PROCESS_EXECUTION) cleanOutputsAndLocalState(outputFiles, log, metrics, reason = "in-process execution strategy is non-incremental") - metrics.startMeasure(BuildTime.NON_INCREMENTAL_COMPILATION_IN_PROCESS, System.nanoTime()) + metrics.startMeasure(BuildTime.NON_INCREMENTAL_COMPILATION_IN_PROCESS) // in-process compiler should always be run in a different thread // to avoid leaking thread locals from compiler (see KT-28037) val threadPool = Executors.newSingleThreadExecutor() @@ -338,7 +335,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( bufferingMessageCollector.flush(messageCollector) threadPool.shutdown() - metrics.endMeasure(BuildTime.NON_INCREMENTAL_COMPILATION_IN_PROCESS, System.nanoTime()) + metrics.endMeasure(BuildTime.NON_INCREMENTAL_COMPILATION_IN_PROCESS) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatListener.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatListener.kt index 61f4959f983..6094af5dfd1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatListener.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatListener.kt @@ -59,7 +59,7 @@ class KotlinBuildStatListener(val projectName: String, val reportStatistics: Lis if (event is TaskFinishEvent) { val result = event.result val taskPath = event.descriptor.taskPath - val duration = result.endTime - result.startTime + val durationMs = result.endTime - result.startTime val taskResult = when (result) { is TaskSuccessResult -> when { result.isFromCache -> TaskExecutionState.FROM_CACHE @@ -72,7 +72,7 @@ class KotlinBuildStatListener(val projectName: String, val reportStatistics: Lis else -> TaskExecutionState.UNKNOWN } - reportData(taskPath, duration, taskResult) + reportData(taskPath, durationMs, taskResult) } } if (measuredTimeMs > LIMIT_DURATION_MS) { @@ -80,15 +80,16 @@ class KotlinBuildStatListener(val projectName: String, val reportStatistics: Lis } } - private fun reportData(taskPath: String, duration: Long, taskResult: TaskExecutionState) { + private fun reportData(taskPath: String, durationMs: Long, taskResult: TaskExecutionState) { val (reportDataDuration, compileStatData) = measureTimeMillisWithResult { if (!availableForStat(taskPath)) { return } val taskExecutionResult = TaskExecutionResults[taskPath] - val timeData = taskExecutionResult?.buildMetrics?.buildTimes?.asMap()?.filterValues { value -> value != 0L } ?: emptyMap() - val perfData = taskExecutionResult?.buildMetrics?.buildPerformanceMetrics?.asMap()?.filterValues { value -> value != 0L } ?: emptyMap() + val buildTimesMs = taskExecutionResult?.buildMetrics?.buildTimes?.asMapMs()?.filterValues { value -> value != 0L } ?: emptyMap() + val perfData = + taskExecutionResult?.buildMetrics?.buildPerformanceMetrics?.asMap()?.filterValues { value -> value != 0L } ?: emptyMap() val changes = when (val changedFiles = taskExecutionResult?.taskInfo?.changedFiles) { is ChangedFiles.Known -> changedFiles.modified.map { it.absolutePath } + changedFiles.removed.map { it.absolutePath } is ChangedFiles.Dependencies -> changedFiles.modified.map { it.absolutePath } + changedFiles.removed.map { it.absolutePath } @@ -96,8 +97,8 @@ class KotlinBuildStatListener(val projectName: String, val reportStatistics: Lis } val compileStatData = CompileStatData( - duration = duration, taskResult = taskResult.name, label = label, - timeData = timeData, perfData = perfData, projectName = projectName, taskName = taskPath, changes = changes, + durationMs = durationMs, taskResult = taskResult.name, label = label, + buildTimesMs = buildTimesMs, perfData = perfData, projectName = projectName, taskName = taskPath, changes = changes, tags = taskExecutionResult?.taskInfo?.properties?.map { it.name } ?: emptyList(), nonIncrementalAttributes = taskExecutionResult?.buildMetrics?.buildAttributes?.asMap() ?: emptyMap(), hostName = hostName, kotlinVersion = "1.6", buildUuid = buildUuid, timeInMillis = System.currentTimeMillis() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt index f971f2560d6..1b2627925e7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt @@ -16,7 +16,7 @@ data class CompileStatData( val label: String?, val taskName: String?, val taskResult: String, - val duration: Long, + val durationMs: Long, val tags: List, val changes: List, val buildUuid: String = "Unset", @@ -25,7 +25,7 @@ data class CompileStatData( val timeInMillis: Long, val timestamp: String = formatter.format(timeInMillis), val nonIncrementalAttributes: Map, - val timeData: Map, + val buildTimesMs: Map, val perfData: Map ) { companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToBuildScan.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToBuildScan.kt index 897f1ad9f78..8f7f2f395b7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToBuildScan.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToBuildScan.kt @@ -50,8 +50,9 @@ class ReportStatisticsToBuildScan( } data.changes.joinTo(readableString, prefix = "Changes: [", postfix = "]; ") { it.substringAfterLast(File.separator) } - val timeData = data.timeData.map { (key, value) -> "${key.readableString}: ${value}ms"} //sometimes it is better to have separate variable to be able debug - val perfData = data.perfData.map { (key, value) -> "${key.readableString}: ${readableFileLength(value)}"} + val timeData = + data.buildTimesMs.map { (key, value) -> "${key.readableString}: ${value}ms" } //sometimes it is better to have separate variable to be able debug + val perfData = data.perfData.map { (key, value) -> "${key.readableString}: ${readableFileLength(value)}" } timeData.union(perfData).joinTo(readableString, ",", "Performance: [", "]") return splitStringIfNeed(readableString.toString(), lengthLimit) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsReporterService.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsReporterService.kt index f63ca50d30a..29fef340a78 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsReporterService.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsReporterService.kt @@ -24,10 +24,8 @@ import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData import org.jetbrains.kotlin.gradle.report.data.BuildExecutionDataProcessor import org.jetbrains.kotlin.gradle.report.data.TaskExecutionData -import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedQueue -import kotlin.collections.ArrayList abstract class BuildMetricsReporterService : BuildService, OperationCompletionListener, AutoCloseable { @@ -69,7 +67,7 @@ abstract class BuildMetricsReporterService : BuildService k.name } - val buildPerfMetrics = data.buildMetrics.buildPerformanceMetrics.asMap().mapKeys { (k, _) -> k.name } - val buildAttributes = data.buildMetrics.buildAttributes.asMap().mapKeys { (k, _) -> k.name } - buildMetricsData.taskData[path] = + buildMetricsData.taskData[data.taskPath] = TaskData( - path = path, - typeFqName = type, - timeMetrics = buildTimes, - performanceMetrics = buildPerfMetrics, - buildAttributes = buildAttributes, + path = data.taskPath, + typeFqName = data.type, + buildTimesMs = data.buildMetrics.buildTimes.asMapMs().mapKeys { it.key.name }, + performanceMetrics = data.buildMetrics.buildPerformanceMetrics.asMap().mapKeys { it.key.name }, + buildAttributes = data.buildMetrics.buildAttributes.asMap().mapKeys { it.key.name }, didWork = data.didWork ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt index e3db050c65b..e440539fa6a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/report/PlainTextBuildReportWriter.kt @@ -15,8 +15,6 @@ import java.io.File import java.io.Serializable import java.text.SimpleDateFormat import java.util.* -import kotlin.collections.ArrayList -import kotlin.collections.HashSet import kotlin.math.max internal class PlainTextBuildReportWriterDataProcessor( @@ -88,9 +86,9 @@ internal class PlainTextBuildReportWriter( } private fun printBuildTimes(buildTimes: BuildTimes) { - val collectedBuildTimes = buildTimes.asMap() + val buildTimesMs = buildTimes.asMapMs() - if (collectedBuildTimes.isEmpty()) return + if (buildTimesMs.isEmpty()) return p.println("Time metrics:") p.withIndent { @@ -98,7 +96,7 @@ internal class PlainTextBuildReportWriter( fun printBuildTime(buildTime: BuildTime) { if (!visitedBuildTimes.add(buildTime)) return - val timeMs = collectedBuildTimes[buildTime] + val timeMs = buildTimesMs[buildTime] if (timeMs != null) { p.println("${buildTime.name}: ${formatTime(timeMs)}") p.withIndent {