Search

Time measurement

Kotlin 표준 라이브러리는 다양한 단위로 시간을 계산하고 측정할 수 있는 도구를 제공한다.
정확한 시간 측정은 다음과 같은 활동에 중요하다.
스레드 또는 프로세스 관리
통계 수집
타임아웃 감지
디버깅
기본적으로 시간은 단조로운 시간 소스를 사용하여 측정되지만 다른 시간 소스를 구성할 수도 있다.

기간 계산

시간의 양을 나타내기 위해 표준 라이브러리는 Duration 클래스를 제공한다.
Duration 은 다음의 DurationUnit 열거형 클래스에 정의된 단위로 표현될 수 있다.
NANOSECONDS
MICROSECONDS
MILLISECONDS
SECONDS
MINUTES
HOURS
DAYS
Duration 은 양수, 음수, 제로, 양의 무한대, 음의 무한대를 가질 수 있다.

기간 생성

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
Kotlin
복사
Duration 을 생성하려면 Int, Long, Double 타입에서 사용할 수 있는 확장 속성을 이용한다.
예를 들어, nanoseconds, microseconds, milliseconds, seconds, minutes, hours, days 가 있다.

기간 산술

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
Kotlin
복사
Duration 객체에 대해 기본적인 산술 연산을 수행할 수 있다.

문자열 표현 가져오기

// 초 단위로 2자리 소수점으로 출력 println(5887.milliseconds.toString(DurationUnit.SECONDS, 2)) // 5.89s
Kotlin
복사
Duration의 문자열 표현이 필요할 때는 .toString() 함수를 사용한다.
기본적으로 시간은 존재하는 각 단위를 사용하여 1h 0m 45.677s 와 같은 형식으로 보고된다.
출력을 구성하려면 .toString() 함수를 원하는 DurationUnit 과 소수점 자리 수를 매개변수로 사용한다.
println(86420.seconds.toIsoString()) // PT24H0M20S
Kotlin
복사
ISO-8601 호환 문자열을 얻으려면 toIsoString() 함수를 사용한다.

기간 변환

val thirtyMinutes: Duration = 30.minutes println(thirtyMinutes.inWholeSeconds) // 1800
Kotlin
복사
Duration 을 다른 DurationUnit 으로 변환하려면 다음 속성을 사용한다.
inWholeNanoseconds
inWholeMicroseconds
inWholeSeconds
inWholeMinutes
inWholeHours
inWholeDays
println(270.seconds.toDouble(DurationUnit.MINUTES)) // 4.5
Kotlin
복사
또는 원하는 DurationUnit 을 함수 매개변수로 사용하여 다음 확장 함수를 사용할 수 있다.

기간 비교

val thirtyMinutes: Duration = 30.minutes val halfHour: Duration = 0.5.hours println(thirtyMinutes == halfHour) // true
Kotlin
복사
Duration 객체가 같은지 확인하려면 등호 연산자(==)를 사용한다.
println(3000.microseconds < 25000.nanoseconds) // false
Kotlin
복사
Duration 객체를 비교하려면 비교 연산자(<, >)를 사용한다.

기간을 구성 요소로 나누기

val thirtyMinutes: Duration = 30.minutes println(thirtyMinutes.toComponents { hours, minutes, _, _ -> "${hours}h:${minutes}m" }) // 0h:30m
Kotlin
복사
Duration 을 시간 구성 요소로 나누고 추가 작업을 수행하려면 toComponents() 함수의 오버로드를 사용한다.
원하는 작업을 함수 또는 람다 표현식으로 매개변수로 추가한다.

시간 측정

시간의 경과를 추적하기 위해 표준 라이브러리는 다음과 같은 도구를 제공한다.
코드 실행에 걸린 시간을 원하는 시간 단위로 측정한다.
특정 순간을 표시한다.
두 순간의 시간을 비교하고 빼기 연산을 수행한다.
특정 순간 이후 얼마나 시간이 지났는지 확인한다.
현재 시간이 특정 순간을 지나쳤는지 확인한다.

코드 실행 시간 측정

val timeTaken = measureTime { Thread.sleep(100) } println(timeTaken) // 예: 103 ms
Kotlin
복사
코드 블록의 실행에 걸린 시간을 측정하려면 measureTime 인라인 함수를 사용한다.
val (value, timeTaken) = measureTimedValue { Thread.sleep(100) 42 } println(value) // 42 println(timeTaken) // 예: 103 ms
Kotlin
복사
코드 블록의 실행에 걸린 시간을 측정하고 코드 블록의 값을 반환하려면 measureTimedValue 인라인 함수를 사용한다.

순간 표시

import kotlin.time.* fun main() { val timeSource = TimeSource.Monotonic val mark = timeSource.markNow() }
Kotlin
복사
특정 순간을 표시하려면 TimeSource 인터페이스와 markNow() 함수를 사용하여 TimeMark 를 생성한다.

시간차 측정

val timeSource = TimeSource.Monotonic val mark1 = timeSource.markNow() Thread.sleep(500) // 0.5초 대기 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) // true, mark2가 mark1보다 늦게 캡처되었기 때문
Kotlin
복사
같은 시간 소스에서 TimeMark 객체 간의 차이를 측정하려면 빼기 연산자를 사용한다.
같은 시간 소스에서 TimeMark 객체를 비교하려면 비교 연산자(<, >)를 사용한다.

기간 확인

val timeSource = TimeSource.Monotonic val mark1 = timeSource.markNow() val fiveSeconds: Duration = 5.seconds val mark2 = mark1 + fiveSeconds // 아직 5초가 지나지 않았음 println(mark2.hasPassedNow()) // false // 6초 대기 Thread.sleep(6000) println(mark2.hasPassedNow()) // true
Kotlin
복사
기한이 지났는지 또는 타임아웃이 발생했는지 확인하려면 hasPassedNow()hasNotPassedNow() 확장 함수를 사용한다.

시간 소스

기본적으로 시간은 단조로운 시간 소스를 사용하여 측정된다.
단조로운 시간 소스는 앞으로만 움직이며 시간대와 같은 변동의 영향을 받지 않는다.
단조로운 시간의 대안은 실제 경과 시간으로 벽 시계 시간이라고도 불린다.
실제 경과 시간은 다른 시점을 기준으로 측정된다.

플랫폼별 기본 시간 소스

플랫폼
소스
Kotlin/JVM
System.nanoTime()
Kotlin/JS (Node.js)
process.hrtime()
Kotlin/JS (브라우저)
window.performance.now() 또는 Date.now()
Kotlin/Native
std::chrono::high_resolution_clock 또는 std::chrono::steady_clock

시간 소스 생성

특정 시간 소스를 사용해야 하는 경우도 있다.
object RealtimeMonotonicTimeSource : AbstractLongTimeSource(DurationUnit.NANOSECONDS) { override fun read(): Long = SystemClock.elapsedRealtimeNanos() }
Kotlin
복사
예를 들어, Android에서 System.nanoTime() 은 기기가 활성 상태일 때만 시간을 측정한다.
기기가 깊은 잠에 들어가면 시간을 잃게 되고 그 때 시간을 추적하려면 SystemClock.elapsedRealtimeNanos() 를 사용하는 시간 소스를 생성할 수 있다.
fun main() { val elapsed: Duration = RealtimeMonotonicTimeSource.measureTime { Thread.sleep(100) } println(elapsed) // 예: 103 ms }
Kotlin
복사
그런 다음 시간 측정을 위해 해당 시간 소스를 사용할 수 있다.