When to use and do not use an inline function in Kotlin?

Technology CommunityCategory: KotlinWhen to use and do not use an inline function in Kotlin?
VietMX Staff asked 3 years ago

Using higher-order functions imposes certain runtime penalties: each function is an object, and it captures a closure, i.e. those variables that are accessed in the body of the function. Memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead.

But it appears that in many cases this kind of overhead can be eliminated by inlining the lambda expressions.

The inline modifier affects both the function itself and the lambdas passed to it: all of those will be inlined into the call site.

The most important case when we use inline modifier is when we define util-like functions with parameter functions. This is why inline modifier is mostly an important optimization for library developers.

Consider:

inline fun inlined(block: () -> Unit) {
    println("before")
    block()
    println("after")
}

inlined {
    println("do something here")
}

// No Function object instance will be created, instead, the code around the 
// invocation of block inside the inlined function will be copied 
// to the call site
System.out.println("before");
System.out.println("do something here");
System.out.println("after");

When we don’t have function type parameter, reified type parameter, and we don’t need non-local return, then we most likely shouldn’t use inline modifier.

Also there is the code size problem. Inlining a large function could dramatically increase the size of the bytecode because it’s copied to every calls site. Inlining may cause the generated code to grow; however, if we do it in a reasonable way (i.e. avoiding inlining large functions), it will pay off in performance.