Inline functions in Kotlin

The inline function in Kotlin is still fun

  • Why do I need inline functions?

Lambda expressions are normally compiled into anonymous classes. This means that each time a lambda expression is called, an additional class is created. And if lambda captures a variable, a new object will be created every time it is called. This incurs additional runtime overhead, resulting in lower efficiency using lambda than using a function that directly executes the same code.

  • What is the function of inline function?

It can eliminate the performance overhead brought by lambda and make the control flow in lambda more flexible Inline functions are marked with the inline modifier. When the inline function is used, the compiler will not generate the code of the function call, but replace each function call with the real code of the function implementation

  • How do inline functions work?

When a function is declared as inline, its function body is inline - in other words, the function will be directly replaced to the place where the function is called instead of being called normally. Take a look at an example to understand the resulting code

For example:

inline fun <T> synchronized(lock: Lock, action: () -> T): T {
lock.lock()
try {
return action()
} finally {
lock.unlock()
}
} f
un main(args: Array<String>) {
println("implement synchronized before")
val lock: Lock = TestLock()
synchronized(lock) {
println("do cus action--inline")
} p
rintln("implement synchronized after")
}

Because the synchronized function is inline, anonymous objects will not be built during compilation. Therefore, the bytecode after compilation of the above main function is equivalent to:

fun main(args: Array<String>) {
println("implement synchronized before")
val lock: Lock = TestLock()
//Inline function body
lock.lock()
try {
println("do cus action--inline")
} finally {
lock.unlock()
} p
rintln("implement synchronized after")
}
  • Using the inline keyword can only improve the performance of functions with lambda parameters,

for example

fun setArrayNumber(array:Array<Number>) {
var str:String = "Array elements are arranged in order"
for (item in array) {
str = str + item.toString() + ", "
} t
v_function_result.text = st
}

In kotlin, Int, Long and Double inherit from Number. However, if we pass in Array when calling the above function, an error will be reported!! This is inconsistent with JAVA. Because kotlin requires that the parameter class name must be exactly the same when calling the function!!

For the above function, if we want to receive both Array and Array, we can define an inline function that materializes type parameters Only inline functions can materialize type parameters (qualified parameter types)

//Inline is added in front of fun to indicate the inline function, < verified param: Number > indicates that param needs to be a subclass of Number
inline fun<reified param:Number> setArrayNumber2(array:Array<param>) {
var str:String = "Array elements are arranged in order"
for (item in array) {
str = str + item.toString() + ", "
} p
rintln(str)
}
 ```

> call

```kotlin
var int_array:Array<Int> = arrayOf(1, 2, 3)
var float_array:Array<Float> = arrayOf(1.0f, 2.0f, 3.0f)
var double_array:Array<Double> = arrayOf(11.11, 22.22, 33.33)
btn_generic_number.setOnClickListener {
when (count%3) {
0 -> setArrayStr<Int>(int_array)
1 -> setArrayStr<Float>(float_array)
else -> setArrayStr<Double>(double_array)
} c
ount++
}

Special attention should be paid to:

When calling an inline function, the code of the function will be copied directly out of the call, and it will be copied 10 times after 10 calls, instead of directly referring to the function address like an ordinary function.

Added by Gast on Tue, 22 Feb 2022 08:43:55 +0200