Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Optimizing Kotlin Performance with Inline Functions

Tech 2

Inline Functions

Higher-order functions in Kotlin can incur runtime overhead due to function objects and closure capture, leading to memory allocation and virtual call costs. Inline functions mitigate this by copying the function's bytecode directly into the call site, eliminating these overheads.

For example, consider a lock function:

inline fun <T> synchronized(lockObj: Lock, operation: () -> T): T {
    lockObj.lock()
    try {
        return operation()
    } finally {
        lockObj.unlock()
    }
}

When called as synchronized(lock) { performTask() }, the compiler generates code equivalent to:

lock.lock()
try {
    performTask()
} finally {
    lock.unlock()
}

This avoids creating a function object for the lambda parameter.

Controlling Inlining with noinline

To prevent specific lambda parameters from being inlined, use the noinline modifier:

inline fun process(
    inlineBlock: () -> Unit,
    noinline deferredBlock: () -> Unit
) {
    inlineBlock()
    val storedAction = deferredBlock // Can be stored or passed
}

noinline parameters can be manipulated freely, such as stored in variables or passed to other functions.

Non-Local Returns

In regular lambda expressions, a return statement is restricted to exiting the lambda itself. However, inline lambdas support non-local returns, allowing control to exit the enclosing function:

fun findValue(values: List<Int>): Boolean {
    values.forEach {
        if (it == 42) return true // Exits findValue
    }
    return false
}

This works because the lambda is inlined into the calling context.

Crossinline Lambdas

When a lambda is executed in a different context (e.g., within a local object), non-local returns are disallowed. Mark such parameters with crossinline:

inline fun executeAsync(crossinline task: () -> Unit) {
    val runnable = object : Runnable {
        override fun run() = task()
    }
    // Execute runnable
}

This ensures the lambda does not perform non-local returns.

Reified Type Parameters

Inline functions can use reifeid type parameters to access type information at runtime without reflection:

inline fun <reified T> findParentOfType(node: TreeNode): T? {
    var current = node.parent
    while (current != null && current !is T) {
        current = current.parent
    }
    return current as T?
}

Call it concisely: node.findParentOfType<SpecificNode>().

Reified types also work with reflection if needed:

inline fun <reified T> listMembers() = T::class.members

Inline Properties

From Kotlin 1.1, inline modifiers can apply to property accessors without backing fields:

val computedValue: Int
    inline get() = 42

var managedState: String
    get() = fetchState()
    inline set(value) { updateState(value) }

Or inline the entire property:

inline var counter: Int
    get() = readCount()
    set(value) { writeCount(value) }

Restrictions on Public API Inline Functions

Public or protceted inline functions are considered module-level APIs. To maintain binary compatibility, their bodies cannot reference private or internal declarations unless annotated with @PublishedApi:

@PublishedApi
internal fun helper() { /* ... */ }

inline fun publicApiFunction() {
    helper() // Allowed due to @PublishedApi
}

This prevents incompatibilities when modules are updated independently.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.