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.
The 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, filter
and filterNotInline
. The former is part of the Kotlin standard library and the latter is a copy of it with inline
removed.
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 println
statement.
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
noinline
on individual parameters to prevent copying. - Regular
return
statements 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.
Top comments (0)