skip to content

When should you mark your own function `inline`, and when is it a mistake? Give the rule of thumb the compiler itself nudges you toward.

level: middleimportance: should knowfreq 55%

answer

  1. Inline = small + lambda param
  2. No functional param -> compiler warns (insignificant)
  3. Large body -> bytecode bloat at every call site
  4. reified requires inline
  5. Public API -> binary-compat caution

basics

~20 s

Mark a small function inline when it takes a lambda and you want to avoid creating an object for that lambda. Don't inline big functions or ones without lambda parameters — it just bloats the code with no real benefit.

solid answer

~40 s

Use `inline` for **small** higher-order functions whose main job is to invoke a lambda parameter — that's where you save the `FunctionN` allocation and `invoke()` dispatch and where non-local return / `reified` become available. Avoid it when: the function has **no functional parameters** (the compiler warns the benefit is insignificant — the only reason then is `reified`); the body is **large** (inlining duplicates that bytecode at every call site, growing binary size and possibly hurting instruction cache); or the function is part of a **public API** where inlining bakes implementation details into callers and can break binary compatibility on change. The rule of thumb: inline tiny lambda-taking utilities (like the stdlib scope functions); leave everything else non-inline and trust the JIT.

go deeper

for a junior

Knows inline is for small functions that take lambdas.

for a middle

States the no-functional-param compiler warning and the bytecode-bloat downside for large bodies.

for a senior

Adds reified-requires-inline and the public-API/binary-compatibility caveat; mentions trusting the JIT for ordinary calls.

for a principal

Frames a codebase-wide policy: which utilities to inline, how to factor large HOFs, and the maintenance cost of inlining across module boundaries.

## The decision `inline` is a performance tool with a code-size cost. Decide per function. ### Mark it `inline` when - The function **takes one or more lambda parameters** and is **small**. - It's a hot utility where avoiding the per-call **`FunctionN` allocation** and **`invoke()` dispatch** matters — e.g. loop bodies, scope-function-like helpers. - You need an **inline-only feature**: **non-local `return`** from the lambda, or a **`reified` type parameter** (which requires `inline`). ```kotlin inline fun <reified T> Bundle.getTyped(key: String): T? = get(key) as? T // reified needs inline ``` ### Don't inline when - **No functional parameters.** There's nothing to save; the compiler emits a warning like *"Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of function types."* Only justify it for `reified`. - **The body is large.** Inlining **duplicates the bytecode at every call site**. A big function called in 50 places multiplies its size 50×, bloating the artifact and pressuring the instruction cache — which can be *slower*. - **Public/library API.** Inlining copies your implementation into every consumer's bytecode, so changing the body requires recompiling callers and inlined private members must be made effectively visible; it weakens binary compatibility. ## Trust the JIT for ordinary calls For non-HOF functions, the JVM's JIT already inlines hot methods at runtime. Adding `inline` there gains little and costs size. ## A pragmatic checklist - Small + has lambda param → `inline` is a good default. - Has lambda param but **large** → consider extracting the non-inline heavy part, or use `noinline`/`crossinline` on specific params (separate facets). - No lambda param, need `reified` → `inline` is required. - No lambda param, no `reified` → **don't**. ## Why the compiler nudges you Kotlin deliberately warns on pointless `inline` so people don't sprinkle it as a magic 'go faster' keyword. The benefit is specifically about lambda handling and inline-only features, not general speed.

  • What's the one reason to inline a function with no lambda parameters?
    To use a `reified` type parameter, which is only legal on an `inline` function because the actual type must be substituted at the call site.
  • Why is inlining risky for a published library function?
    Its body is copied into every caller's compiled code, so changing it can break binary compatibility and requires consumers to recompile; private members it touches must also become accessible.

Inlining is salt: a pinch on a lambda-taking helper improves it; dumping it on every function just ruins the dish (bloats the code).

saying these in an interview costs you the question

  • Recommending `inline` on everything 'for speed'
  • Inlining a large function and ignoring code-size blowup
  • Not knowing the compiler warns on no-functional-param inline
  • Unaware that reified requires inline
  • Ignoring binary-compatibility concerns for public API

context