Kotlin allows functions to be passed and returned from other functions. This feature is called "first class" support for functions and brings in advantages of functional programming. To learn about
inline, we will go over the hidden costs of functional programming, see how
inline can help reduce those costs, then wrap up with places where it should not be used.
A higher-order function comes with run-time penalties. First, memory is allocated for lambdas as function parameters. They are compiled to either
Function classes or anonymous classes, and both cost memory. Additionally, anonymous classes are slower than
Function classes and used only when local variables are captured. Lastly, virtual calls add unnecessary cost.
inline keyword was added to Kotlin to reduce the associated costs of higher-order functions. It modifies the Java bytecode by injecting the function and its parameters directly where the function is called, the call site. Using it is easy, just add
inline before your function:
To see how
inline impacts bytecode, consider two functionally equivalent higher-order functions,
filterNotInline. The former is part of the Kotlin standard library and the latter is a copy of it with
Decompiling this code will show how inlining works under-the-hood. Also, it was compiled to JVM bytecode and decompiled to Java for readability. Since
filter is inlined, its code is copied directly. Here's the call site at the first
The less efficient version requires overhead via a function call to
filterNotInline, which contains code similar to the above.
Inlining is usually great for performance, but there are good reasons why functions are not inlined by default:
- Using an inlined function increases code length because the function is copied to every call site. This is especially true for long functions.
- Inlining applies to all lambda parameters of the inlined function. So, an inlined function with three lambdas as parameters will copy them all. You can use
noinlineon individual parameters to prevent copying.
returnstatements are not allowed. You must use a label if you wish to return from your inlined function.
- Inline functions do not have access to data less visible than themselves.
In addition to functions, properties can be inlined too! This can be done at the individual getter and setter or the entire property.
By now you should have an understanding of the benefits and tradeoffs of
inline. Feel free to post any questions you have in the comments!
Did you like what you read? You can also follow me on Twitter for more Android content.