This code compiles with a warning (insignificant performance impact):
inline fun test(noinline f: () -> Unit) {
thread(
Q1: How come (2) does not compile but (4) does?
From their doc:
Inlinable lambdas can only be called inside the inline functions or passed as inlinable arguments...
Answer:
The method thread(...)
is not an inline
method so you won't be able to pass f
as an argument.
Q2: What exactly is the difference between noinline and crossinline?
Answer:
noinline
will prevent the inlining of lambdas. This becomes useful when you have multiple lambda arguments and you want only some of the lambdas passed to an inline function to be inlined.
crossinline
is used to mark lambdas that mustn't allow non-local returns, especially when such lambda is passed to another execution context. In other words, you won't be able to do a use a return
in such lambdas. Using your example:
inline fun test(crossinline f: () -> Unit) {
thread { f() }
}
//another method in the class
fun foo() {
test{
//Error! return is not allowed here.
return
}
}
Q3: If (3) does not generates a no performance improvements, why would (4) do?
Answer:
That is because the only lambda you have in (3) has been marked with noinline
which means you'll have the overhead cost of creating the Function
object to house the body of your lamda. For (4) the lambda is still inlined (performance improvement) only that it won't allow non-local returns.