Inline Functions in Kotlin

Tuğçe Aras
Huawei Developers
Published in
4 min readAug 5, 2023
Inline Functions in Kotlin

Introduction

Hi, everyone👋

Anyone here who wants to improve Kotlin code performance? 🤔 I will talk about Inline functions, which is one of the important functions. I will try to explain what they are, how they are used or how they are kept in the background, etc. At the same time 👇

  • From the use cases of the inline functions
  • What is the noinline keyword?
  • What is the crossinline keyword?
  • What is the reified keyword?

Let’s get started then ✨

🔶 Inline Functions

  • Inline functions are copied to where they were called at compile time.
  • No real function calls are made. All code between the function body is pasted wherever inline functions were called. In this way, no additional function object is created. Memory load is reduced with inline functions.

Let’s look at the following code examples for better understanding. 👇

Let’s write a normal function without using the inline keyword. Then let’s make the same example with the inline function and compare 💥

Normal Function:

Normal function without inline keyword

Now let’s examine it with Show Kotlin Byte Code

Tools -> Kotlin -> Show Kotlin Bytecode -> Decompile ✨

Normal func with kotlin bytecode

As seen in the show Kotlin bytecode, secondFunc() is called normally. What happens if I put the inline keyword at the beginning of secondFunc() ? 🤔

With Inline keyword:

Inline function

Now let’s examine it with Show Kotlin Byte Code

Inline function with bytecode

As you can see the body of secondFunc() is copied to where it was called. A normal function call as above was not made. What good does a call like this do for us? 🤔
As I mentioned above, the function object is not created because the body of the inline function is copied directly to the place where it is called.

NOTE: In order to reduce the memory load of higher order functions or lambda expressions, the “inline” keyword is used to ask the compiler not to allocate memory.

As an example, let’s look at the code below.

In case the inline keyword is not used with higher order functions 👇

Higher Order Function without inline keyword

Now let’s examine it with Show Kotlin Byte Code

Higher Order Func in kotlin bytecode

As you can see in Kotlin bytecode, when we call HigherOrderFunc() it generates Function object.
NOTE: So, what if I want to call this HigherOrderFunc() more than once? 🤔
Each time HigherOrderFunc() is called, a new Function object is created, and memory starts to swell. 😲

That’s why we use the inline keyword. In this way, we avoid creating a new Function object by copying the body of our function to the place where it was called. ❗️❗️❗️

  • Inline functions allow non-local return. For example:
Nonlocal return with inline keyword

🔶 Noinline and Crossinline Keyword

  • When we do not want to inline the parameter in a function that we have created as inline, we put the “noinline” keyword in front of the parameter.
  • If we want the operation to be inline but in a different scope, we use the “crossinline” keyword. Crossinline does not allow non local return. In crossline, object creation does not occur in the background, as in inline.

For example:

fun main(){
test()
}

fun test(){
println("Hello!")
higherOrderFuncExample({
println("crossinline")
},{
println("noinline")
})
}

interface testI{
fun test() : Unit
}

inline fun higherOrderFuncExample(crossinline printInfo: () -> Unit, noinline callback: () -> Unit) {
val test = object : testI{
override fun test(): Unit {
return printInfo.invoke()
}

}
callback()
}

🔶 Reified Keyword

  • Generic types do not know what type they are at compile time. If the reified keyword is used with inline functions, then it is known at compile time what type T can be.
Reified keyword with inline

Now let’s examine it with Show Kotlin Byte Code

Reified in Kotlin Bytecode

Conclusion

Inline functions are a nice function that can be used to improve your code performance. Especially using it together with higher order functions and lambda expressions increases the performance and reduces the memory load.

However, since the body part of the inline functions is directly pasted into the function they are called, the code size may increase and accordingly the bytecode size may increase. Therefore, the use of inline functions with large or complex functions should be avoided.

--

--