Hi, I found that on Kotlin Native, the time-consum...
# kotlin-native
g
Hi, I found that on Kotlin Native, the time-consuming of throwing and catching exceptions is about 5~10 times that of JVM. Is this problem known? Below is my test code, they run on the same device.
Copy code
fun main(args: Array<String>) {
    throwTest()
}

var createExceptionTime: Duration = Duration.ZERO

@OptIn(ExperimentalTime::class)
fun throwTest() {
    repeat(20) {
        createExceptionTime = Duration.ZERO
        measureTime {
            repeat(100) {
                runCatching {
                    throwException(100)
                }
            }
        }.also {
            println("Throw Performance Test:totalTime=$it throwTime=${it - createExceptionTime} createErrorTime=$createExceptionTime")
        }
    }
}


@OptIn(ExperimentalTime::class)
fun throwException(deep: Int) {
    if (deep == 0) throw measureTimedValue { RuntimeException() }.apply { createExceptionTime += duration }.value
    throwException(deep - 1)
}
Logs on Jvm: Throw Performance Test:totalTime=6.928553ms throwTime=5.908972ms createErrorTime=1.019581ms Throw Performance Test:totalTime=1.357407ms throwTime=797.797us createErrorTime=559.61us Throw Performance Test:totalTime=1.215410ms throwTime=649.083us createErrorTime=566.327us Throw Performance Test:totalTime=1.023574ms throwTime=528.187us createErrorTime=495.387us Throw Performance Test:totalTime=973.957us throwTime=488.259us createErrorTime=485.698us Throw Performance Test:totalTime=943.841us throwTime=456.6us createErrorTime=487.241us Throw Performance Test:totalTime=940.144us throwTime=455.628us createErrorTime=484.516us Throw Performance Test:totalTime=954.059us throwTime=454.954us createErrorTime=499.105us Throw Performance Test:totalTime=954.739us throwTime=464.041us createErrorTime=490.698us Throw Performance Test:totalTime=953.431us throwTime=461.697us createErrorTime=491.734us Throw Performance Test:totalTime=946.232us throwTime=456.769us createErrorTime=489.463us Throw Performance Test:totalTime=962.239us throwTime=454.854us createErrorTime=507.385us Throw Performance Test:totalTime=957.696us throwTime=460.617us createErrorTime=497.079us Throw Performance Test:totalTime=956.284us throwTime=467.273us createErrorTime=489.011us Throw Performance Test:totalTime=954.624us throwTime=473.158us createErrorTime=481.466us Throw Performance Test:totalTime=952.835us throwTime=458.23us createErrorTime=494.605us Throw Performance Test:totalTime=936.177us throwTime=454.877us createErrorTime=481.3us Throw Performance Test:totalTime=936.955us throwTime=453.158us createErrorTime=483.797us Throw Performance Test:totalTime=952.953us throwTime=454.16us createErrorTime=498.793us Throw Performance Test:totalTime=932.074us throwTime=455.823us createErrorTime=476.251us Logs on Native:
Task :runReleaseExecutableNative
Throw Performance Test:totalTime=6.699028ms throwTime=6.183869ms createErrorTime=515.159us Throw Performance Test:totalTime=7.806001ms throwTime=7.431287ms createErrorTime=374.714us Throw Performance Test:totalTime=6.487319ms throwTime=6.302656ms createErrorTime=184.663us Throw Performance Test:totalTime=6.939379ms throwTime=6.678405ms createErrorTime=260.974us Throw Performance Test:totalTime=6.550303ms throwTime=6.358103ms createErrorTime=192.2us Throw Performance Test:totalTime=6.354265ms throwTime=6.186179ms createErrorTime=168.086us Throw Performance Test:totalTime=6.395004ms throwTime=6.207162ms createErrorTime=187.842us Throw Performance Test:totalTime=6.308159ms throwTime=6.150593ms createErrorTime=157.566us Throw Performance Test:totalTime=6.553794ms throwTime=6.305356ms createErrorTime=248.438us Throw Performance Test:totalTime=6.257863ms throwTime=6.143301ms createErrorTime=114.562us Throw Performance Test:totalTime=6.256012ms throwTime=6.142164ms createErrorTime=113.848us Throw Performance Test:totalTime=6.403581ms throwTime=6.276113ms createErrorTime=127.468us Throw Performance Test:totalTime=6.257133ms throwTime=6.143897ms createErrorTime=113.236us Throw Performance Test:totalTime=6.224807ms throwTime=6.125721ms createErrorTime=99.086us Throw Performance Test:totalTime=6.252487ms throwTime=6.156452ms createErrorTime=96.035us Throw Performance Test:totalTime=6.167458ms throwTime=6.074793ms createErrorTime=92.665us Throw Performance Test:totalTime=6.258211ms throwTime=6.110785ms createErrorTime=147.426us Throw Performance Test:totalTime=6.206690ms throwTime=6.109968ms createErrorTime=96.722us Throw Performance Test:totalTime=6.157968ms throwTime=6.066772ms createErrorTime=91.196us Throw Performance Test:totalTime=6.203606ms throwTime=6.106344ms createErrorTime=97.262us
c
You are using loops, Java performs better the more often you run a statement. Notice how the execution time in the Java test goes down over time. The execution time of native stays constant.
m
Something I experienced in the past on JVM when using Java, was that the JVM optimized out the stack trace of an exception that was getting thrown too often. And all the logs messages with the stack trace had rolled out of the logs.
r
Yes this just looks like JIT compilation
You can also notice createErrorTime is significantly faster on native
c
Creating a stack trace is generally not comparable on JVM and native as it's completely different mechanics at play. @Gavin Novate if you concerned about performance, do not use Exceptions as they generally have a extreme overhead compared to e.g. returning a sealed class value indicating success/error with result data included
g
@Christian Würthenr Thank you for your suggestion. I'm testing the performance of Compose on iOS, and the code that throws the exception is in the source code of Compose. I think I can test the time-consuming of throwing exceptions in the Compose source code.