https://kotlinlang.org logo
#getting-started
Title
# getting-started
e

elye

02/28/2024, 1:11 PM
When I run the below,
Copy code
fun CharSequence.isMyBlank(): Boolean {
        return indices.all { this[it].isWhitespace() }
    }
It seems slower than when I have it as
Copy code
fun CharSequence.isMyBlank(): Boolean {
        return indices.all { this[it].isWhitespace() }
    }

    public val CharSequence.indices: IntRange
        get() = 0..length - 1
Even though the
indices
implementation above is the same as Kotlin provided one. Anyone know why? A more illustrated question is provided in https://stackoverflow.com/questions/78074675/why-my-identical-indices-implementation-is-faster-than-the-kotlin-provided-one
y

Youssef Shoaib [MOD]

02/28/2024, 1:27 PM
Please benchmark using a proper library like kotlinx benchmark first. That's because the JVM is complicated and there might be a lot of random fluctuations or class loading times etc
s

Szymon Jeziorski

02/28/2024, 1:28 PM
You're right, implementation is identical and performs identical. The problem lies with how you try to benchmark it. When you start any JVM program there is so much going on under the hood (JVM warmup, JIT optimizations, GC etc), that you usually cannot accurately benchmark things by just running them a number of times. Such benchmarks may give you a general idea of how given code performs, but they should not be used for stating that one thing is faster than another if the difference is marginal (just 3ms in your case). For such scenarios proper benchmarking frameworks should be used. Here's a good read about JVM benchmarking: https://www.oracle.com/technical-resources/articles/java/architect-benchmarking.html Also, to prove my point I've benchmarked the code using JMH, here is the benchmark code and its results: code:
Copy code
fun CharSequence.isMyBlank(): Boolean = indices.all { this[it].isWhitespace() }
fun CharSequence.isMyBlank2(): Boolean = indices2.all { this[it].isWhitespace() }

val CharSequence.indices2: IntRange
    get() = 0..length - 1

@State(Scope.Benchmark)
class IsBlankBenchmark {
    private val strings = listOf("     ", "random string", "_", "              ")

    @Benchmark
    fun isMyBlank() = strings.map { it.isMyBlank() }

    @Benchmark
    fun isMyBlank2() = strings.map { it.isMyBlank2() }
}
results:
Copy code
benchmarks summary:
Benchmark                    Mode  Cnt   Score   Error  Units
IsBlankBenchmark.isMyBlank   avgt    3  52.768 ± 1.392  ns/op
IsBlankBenchmark.isMyBlank2  avgt    3  53.414 ± 2.537  ns/op
As you can see, there is pretty much no viable difference whatsoever