Hello, I've been working with the <experimental ti...
# language-proposals
k
Hello, I've been working with the experimental time measurement API recently. I like how the API provides the
measureTimedValue
method to measure time while still allowing capture of the code block result. I found it a little cumbersome to work with the
TimedValue
result though; it isn't very fluent. I made this extension function to help, and I was thinking maybe it would be a good addition to the API?
Copy code
@ExperimentalTime
inline fun <T> TimedValue<T>.capture(block: (Duration) -> Unit): T {
    block(duration)
    return value
}

@ExperimentalTime
fun main() {
    // Without the capture function
    val (result, duration) = measureTimedValue {
        Thread.sleep(500)
        "foobar"
    }
    println("Duration: $duration")
    println("Result: $result")


    // With the capture function
    measureTimedValue {
        Thread.sleep(500)
        "foobar"
    }.capture {
        println("Duration: $it")
    }.also {
        println("Result: $it")
    }
}
(P.S. - I'm not very satisfied with the name
capture
...feel like there's definitely a better word to use, just can't think of it)
r
Maybe just me, but I actually think the destructured version is cleaner and easier to reason about.
k
it breaks the method chain, is the concern I have. I guess my wish is if I have some fluent method chain, and I want to measure the time of some small part of that chain, that I shouldn't have to break the chain to do so
i
Could you show an example of such method chain?
measureTimedValue
is a top-level function, so it already breaks method chains.
k
yeah, hmm...maybe this idea is a little half-baked. I can introduce the measurement using
let
, but then ofc breaking the chain inside the
let
isn't a problem
here's a somewhat contrived example:
Copy code
return "foo".toUpperCase()
    .let {
        measureTimedValue {
            it.replace("F", "B")
        }.capture { 
            println(it)
        }
    }
    .toLowerCase()
a more useful example would probably be something involving timing of
map
/
filter
when working with sequences
i
Perhaps it could be achieved with the existing scope functions:
Copy code
measureTimedValue {
            it.replace("F", "B")
        }.also { 
            println(it.duration)
        }.value
k
oh, that's slick. I think it'll work. Thanks; I'm still sort of new to Kotlin.
e
Also, you can use destructuring in lambda arguments:
Copy code
measureTimedValue {
    Thread.sleep(500)
    "foobar"
}.also { (result, duration) ->
    println(duration)
}