KT-45777: Track build time in nanoseconds instead of milliseconds

to ensure precision (otherwise, rounding errors to milliseconds may
add up and cause unexplainable gaps in the running time).

We can still use milliseconds in the final report after all the precise
sub-build-times have been aggregated.
This commit is contained in:
Hung Nguyen
2022-01-24 09:57:56 +00:00
committed by nataliya.valtman
parent 52a21a4e1a
commit 37c6b1c2dc
14 changed files with 60 additions and 74 deletions
@@ -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 <T> 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)
}
}
@@ -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)
@@ -9,19 +9,23 @@ import java.io.Serializable
import java.util.*
class BuildTimes : Serializable {
private val myBuildTimes = EnumMap<BuildTime, Long>(BuildTime::class.java)
private val buildTimesNs = EnumMap<BuildTime, Long>(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<BuildTime, Long> = myBuildTimes
fun addTimeMs(buildTime: BuildTime, timeMs: Long) = addTimeNs(buildTime, timeMs * 1_000_000)
fun asMapNs(): Map<BuildTime, Long> = buildTimesNs
fun asMapMs(): Map<BuildTime, Long> = buildTimesNs.mapValues { it.value / 1_000_000 }
companion object {
const val serialVersionUID = 0L
@@ -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) {}
}