Reflection is suppose to be a bit time consuming on android. so i was wondering given a function reference like this:
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
is ::isOdd call an unnecessary burden ?
would it be more efficient to not use them ?
UPDATE: doing some light metrics i did the following:
class MainActivity : Activity() {
val numbers = listOf(1, 2, 3)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doRegular()
doReflection()
}
fun isOdd(x: Int) = x % 2 != 0
fun doRegular() {
val start = System.currentTimeMillis()
for (i in 0..999999) {
numbers.filter { it % 2 != 0 }
}
Log.v("myTag", "regular: +${System.currentTimeMillis() - start}")
}
fun doReflection() {
val start = System.currentTimeMillis()
for (i in 0..999999) {
numbers.filter(::isOdd)
}
Log.v("myTag", "reflection: ${System.currentTimeMillis() - start}")
}
}
and the print statement results are:
//*****this was the first attempt before compiler could optimise anything
regular: +577
reflection: 318
//*********
regular: +376
reflection: 327
regular: +593
reflection: 343
regular: +417
reflection: 251
regular: +243
reflection: 238
regular: +241
reflection: 238
regular: +238
reflection: 237
regular: +235
reflection: 247
regular: +237
reflection: 247
regular: +230
reflection: 268
What would you conclude given these results?
update: some are asking why i think its using reflection. its based on this:
This stackoverflow answer seems to state its reflection: and the title for the official doc has reflection as the main heading: hence my confusion.
Surely
::isOddis used for referencing the function, but unless it is really required to use the "reflection", it (reflection) is not used. Similar to how Int are changed intointin the bytecode unless we need to store the reference, if we create collections then only it is represented asjava.lang.Integer.The Kotlin compiler is smart and does the trick behind the hood.
The filter function is inline function that embeds the lambda/reference directly at the call-site without actually using the reflection.
If you see the JVM bytecode, you'll see the following decompiled Java code:
Realistically there is no reflection is involved here.
Sidenote: I've had a similar question over the official Kotlinlang slack at here, and I've got much attention but only 1 reply regarding it is only about metafacory as stated here in softwareengineering stackexchange subdomain.
Here's a ss: