Измерение времени
Стандартная библиотека Kotlin предоставляет инструменты для расчета и измерения времени в различных единицах. Точное измерение времени важно для таких задач, как:
Управление потоками или процессами
Сбор статистики
Обнаружение таймаутов
Отладка
По умолчанию, время измеряется с помощью монотонного источника времени, но можно настроить и другие источники времени. Для получения дополнительной информации см. Настройка источника времени.
Вычисление продолжительности
Для представления промежутка времени стандартная библиотека предоставляет класс Duration. Продолжительность может быть выражена в следующих единицах из перечисления DurationUnit:
NANOSECONDSMICROSECONDSMILLISECONDSSECONDSMINUTESHOURSDAYS
Продолжительность может быть положительной, отрицательной, нулевой, положительной бесконечностью или отрицательной бесконечностью.
Создание продолжительности
Для создания продолжительности используйте расширяющие свойства, доступные для типов Int, Long, и Double: nanoseconds, microseconds, milliseconds, seconds, minutes, hours, и days.
Например:
import kotlin.time.*
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.days
fun main() {
//sampleStart
val fiveHundredMilliseconds: Duration = 500.milliseconds
val zeroSeconds: Duration = 0.seconds
val tenMinutes: Duration = 10.minutes
val negativeNanosecond: Duration = (-1).nanoseconds
val infiniteDays: Duration = Double.POSITIVE_INFINITY.days
val negativeInfiniteDays: Duration = Double.NEGATIVE_INFINITY.days
println(fiveHundredMilliseconds) // 500ms
println(zeroSeconds) // 0s
println(tenMinutes) // 10m
println(negativeNanosecond) // -1ns
println(infiniteDays) // Infinity
println(negativeInfiniteDays) // -Infinity
//sampleEnd
}
Вы также можете выполнять основные арифметические операции с объектами Duration:
import kotlin.time.*
import kotlin.time.Duration.Companion.seconds
fun main() {
//sampleStart
val fiveSeconds: Duration = 5.seconds
val thirtySeconds: Duration = 30.seconds
println(fiveSeconds + thirtySeconds)
// 35s
println(thirtySeconds - fiveSeconds)
// 25s
println(fiveSeconds * 2)
// 10s
println(thirtySeconds / 2)
// 15s
println(thirtySeconds / fiveSeconds)
// 6.0
println(-thirtySeconds)
// -30s
println((-thirtySeconds).absoluteValue)
// 30s
//sampleEnd
}
Получение строкового представления
Полезно иметь строковое представление продолжительности для вывода, сериализации, передачи или хранения.
Для получения строкового представления используйте функцию .toString(). По умолчанию, время отображается с использованием каждой присутствующей единицы. Например: 1h 0m 45.677s или -(6d 5h 5m 28.284s).
Для настройки вывода используйте функцию .toString() с желаемыми параметрами DurationUnit и количеством десятичных знаков.
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.DurationUnit
fun main() {
//sampleStart
// Print in seconds with 2 decimal places
println(5887.milliseconds.toString(DurationUnit.SECONDS, 2))
// 5.89s
//sampleEnd
}
Для получения строки в формате ISO-8601 используйте функцию toIsoString():
import kotlin.time.Duration.Companion.seconds
fun main() {
//sampleStart
println(86420.seconds.toIsoString()) // PT24H0M20S
//sampleEnd
}
Преобразование продолжительности
Для преобразования продолжительности в другие единицы используйте следующие свойства:
inWholeNanosecondsinWholeMicrosecondsinWholeSecondsinWholeMinutesinWholeHoursinWholeDays
Например:
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
fun main() {
//sampleStart
val thirtyMinutes: Duration = 30.minutes
println(thirtyMinutes.inWholeSeconds)
// 1800
//sampleEnd
}
Также вы можете использовать желаемую единицу в качестве параметра в следующих расширяющих функциях:
.toInt().toDouble().toLong()
Например:
import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
fun main() {
//sampleStart
println(270.seconds.toDouble(DurationUnit.MINUTES))
// 4.5
//sampleEnd
}
Сравнение продолжительностей
Для проверки равенства объектов Duration используйте оператор равенства (==):
import kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
fun main() {
//sampleStart
val thirtyMinutes: Duration = 30.minutes
val halfHour: Duration = 0.5.hours
println(thirtyMinutes == halfHour)
// true
//sampleEnd
}
Для сравнения объектов Duration используйте операторы сравнения (<, >):
import kotlin.time.Duration.Companion.microseconds
import kotlin.time.Duration.Companion.nanoseconds
fun main() {
//sampleStart
println(3000.microseconds < 25000.nanoseconds)
// false
//sampleEnd
}
Разбиение продолжительности на компоненты
Для разбиения продолжительности на компоненты времени и последующего выполнения действия используйте перегрузку функции toComponents(). Добавьте необходимое действие в виде функции или лямбда-выражения в качестве параметра.
Например:
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
fun main() {
//sampleStart
val thirtyMinutes: Duration = 30.minutes
println(thirtyMinutes.toComponents { hours, minutes, _, _ -> "${hours}h:${minutes}m" })
// 0h:30m
//sampleEnd
}
В этом примере лямбда-выражение имеет hours и minutes в качестве параметров с нижними подчеркиваниями (_) для неиспользуемых параметров seconds и nanoseconds. Выражение возвращает объединенную строку, используя шаблоны строк, для получения желаемого формата вывода hours и minutes.
Измерение времени
Для отслеживания хода времени стандартная библиотека предоставляет инструменты для:
Измерения времени выполнения кода в заданной единице времени.
Пометки момента времени.
Сравнения и вычитания двух моментов времени.
Определения прошедшего времени с момента определенного момента.
Проверки, является ли текущее время позже определенного момента.
Измерение времени выполнения кода
Для измерения времени выполнения блока кода используйте встроенную функцию measureTime:
import kotlin.time.measureTime
fun main() {
//sampleStart
val timeTaken = measureTime {
Thread.sleep(100)
}
println(timeTaken) // e.g. 103 ms
//sampleEnd
}
Для измерения времени выполнения блока кода и возврата значения блока кода используйте встроенную функцию measureTimedValue.
Например:
import kotlin.time.measureTimedValue
fun main() {
//sampleStart
val (value, timeTaken) = measureTimedValue {
Thread.sleep(100)
42
}
println(value) // 42
println(timeTaken) // e.g. 103 ms
//sampleEnd
}
По умолчанию обе функции используют монотонный источник времени.
Пометка моментов времени
Для пометки конкретного момента времени используйте интерфейс TimeSource и функцию markNow() для создания объекта TimeMark:
import kotlin.time.*
fun main() {
val timeSource = TimeSource.Monotonic
val mark = timeSource.markNow()
}
Измерение разницы во времени
Для измерения разницы между объектами TimeMark из одного источника времени используйте оператор вычитания (-).
Для сравнения объектов TimeMark из одного источника времени используйте операторы сравнения (<, >).
Например:
import kotlin.time.*
fun main() {
//sampleStart
val timeSource = TimeSource.Monotonic
val mark1 = timeSource.markNow()
Thread.sleep(500) // Sleep 0.5 seconds.
val mark2 = timeSource.markNow()
repeat(4) { n ->
val mark3 = timeSource.markNow()
val elapsed1 = mark3 - mark1
val elapsed2 = mark3 - mark2
println("Measurement 1.${n + 1}: elapsed1=$elapsed1, elapsed2=$elapsed2, diff=${elapsed1 - elapsed2}")
}
println(mark2 > mark1) // This is true, as mark2 was captured later than mark1.
// true
//sampleEnd
}
Для проверки достижения дедлайна или таймаута используйте расширяющие функции hasPassedNow() и hasNotPassedNow():
import kotlin.time.*
import kotlin.time.Duration.Companion.seconds
fun main() {
//sampleStart
val timeSource = TimeSource.Monotonic
val mark1 = timeSource.markNow()
val fiveSeconds: Duration = 5.seconds
val mark2 = mark1 + fiveSeconds
// It hasn't been 5 seconds yet
println(mark2.hasPassedNow())
// false
// Wait six seconds
Thread.sleep(6000)
println(mark2.hasPassedNow())
// true
//sampleEnd
}
Источники времени
По умолчанию время измеряется с помощью монотонного источника времени. Монотонные источники времени движутся только вперед и не зависят от таких факторов, как часовые пояса. Альтернативой монотонному времени является реальное прошедшее время, также известное как время по часам. Реальное прошедшее время измеряется относительно другой точки во времени.
Источники времени по умолчанию для каждой платформы
В этой таблице показан стандартный источник монотонного времени для каждой платформы:
Платформа |
Источник |
|---|---|
Kotlin/JVM |
|
Kotlin/JS (Node.js) |
|
Kotlin/JS (браузер) |
|
Kotlin/Native |
|
Создание источника времени
В некоторых случаях вам может потребоваться использовать другой источник времени. Например, в Android, System.nanoTime() считает время только пока устройство активное. Оно теряет отслеживание времени, когда устройство переходит в глубокий сон. Чтобы отслеживать время, когда устройство находится в глубоком сне, вы можете создать источник времени, который использует SystemClock.elapsedRealtimeNanos():
object RealtimeMonotonicTimeSource : AbstractLongTimeSource(DurationUnit.NANOSECONDS) {
override fun read(): Long = SystemClock.elapsedRealtimeNanos()
}
Затем вы можете использовать свой источник времени для измерения времени:
fun main() {
val elapsed: Duration = RealtimeMonotonicTimeSource.measureTime {
Thread.sleep(100)
}
println(elapsed) // e.g. 103 ms
}
Для получения дополнительной информации о пакете kotlin.time, см. нашу ссылку на API стандартной библиотеки.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/time-measurement.html