You need to time a block and also keep the result. Compare doing it manually with markNow()/elapsedNow() versus measureTime/measureTimedValue, and when does the manual TimeMark approach win?
answer
- measureTime -> Duration; measureTimedValue -> TimedValue(value+duration)
- Both are inline and built on markNow/elapsedNow
- Raw marks for non-lexical start/stop
- Marks for deadlines, splits, comparison
- Both have TimeSource extension overloads (testable)
basics
~20 sFor timing one self-contained block, measureTime { } (returns a Duration) or measureTimedValue { } (returns both the value and Duration) is cleanest. Use manual markNow()/elapsedNow() when the start and end are in different places, like a deadline or multi-stage timing.
solid answer
~30 smeasureTime { } and measureTimedValue { } are stdlib inline helpers that internally do markNow() then elapsedNow() around your lambda, returning a Duration (or TimedValue<T> with .value and .duration). They are the idiomatic choice for a single contiguous block. The raw TimeMark API wins when timing spans non-lexical boundaries: you keep a mark as a field and check elapsedNow() later (cache TTL), build a deadline with markNow() + timeout and poll hasPassedNow(), measure several intermediate splits from one start mark, or compare/subtract marks. measureTimedValue also exists as a TimeSource extension so you can pass a TestTimeSource for deterministic timing tests.
code
kotlin · 19 linesimport kotlin.time.TimeSource
import kotlin.time.measureTimedValue
// block-scoped: cleanest
fun load(): Pair<String, kotlin.time.Duration> {
val r = measureTimedValue { fetch() }
return r.value to r.duration
}
// free-form: mark outlives the block (lap splits)
fun stages() {
val start = TimeSource.Monotonic.markNow()
a(); println("a done at " + start.elapsedNow())
b(); println("b done at " + start.elapsedNow())
}
fun fetch() = "data"
fun a() {}
fun b() {}go deeper
Knows measureTime { } gives the duration of a block.
Chooses measureTimedValue for value+duration and switches to raw marks for non-lexical timing/deadlines.
Notes both helpers are inline, built on markNow/elapsedNow, and have TimeSource extension overloads for deterministic testing.
Sets a team convention for which API to use where and justifies it by scope (lexical vs free-form) and testability.
## Two ways to time Both are built on the same primitive (`markNow()` + `elapsedNow()`), so the question is ergonomics and scope. ### measureTime / measureTimedValue (block-scoped) ```kotlin import kotlin.time.measureTime import kotlin.time.measureTimedValue val d = measureTime { heavyWork() } // Duration println("took $d") val timed = measureTimedValue { compute() } // TimedValue<T> println("${timed.value} in ${timed.duration}") ``` `measureTime` returns a `Duration`; `measureTimedValue` returns a `TimedValue<T>` exposing `.value` (the lambda's result) and `.duration`. Both are `inline`, so the lambda isn't an extra object. Both also exist as **extensions on `TimeSource`** (`source.measureTime { }`), letting you time against a `TestTimeSource` for deterministic tests. Use these when start and end are in the same lexical block — the common case. ### Raw markNow()/elapsedNow() (free-form) ```kotlin val start = TimeSource.Monotonic.markNow() stage1() val afterStage1 = start.elapsedNow() stage2() val total = start.elapsedNow() ``` The manual API is the right tool when: - **Start and stop are far apart**: store a mark as a class field, check `elapsedNow()` in a later method (e.g. cache entry freshness, idle timers). - **Deadlines**: `val deadline = markNow() + timeout`, then loop on `deadline.hasNotPassedNow()`. - **Multiple splits** from one start mark (lap timing). - **Comparing/subtracting marks** (`m2 - m1`, ordering). ## Rule of thumb Contiguous block, want the duration (and maybe the value)? Reach for `measureTime` / `measureTimedValue`. Anything where the mark must outlive a single block or you need arithmetic/comparison? Hold the `TimeMark` yourself. ## Note on scope This leaf is about the mark API; `measureTime`/`measureTimedValue` are covered in their own sibling leaf — here they're the contrast that clarifies *when raw marks are the better choice*.
- What does measureTimedValue return that measureTime does not?A TimedValue<T> carrying both the lambda's result (.value) and the elapsed .duration, whereas measureTime returns only the Duration.
- How would you make a measureTime call deterministic in a test?Use the TimeSource extension overload: testTimeSource.measureTime { ... } and advance the TestTimeSource inside, so the measured duration is exactly what you advanced.
saying these in an interview costs you the question
- Reaching for raw markNow/elapsedNow for a simple contiguous block
- Thinking measureTime can return the computed value (it returns only Duration)
- Not knowing measureTimedValue exists for value+duration
- Believing measureTime cannot be made deterministic in tests