Skip to content
Tech News
← Back to articles

The Cost of Indirection in Rust

read original get Rust Compiler → more articles

Why 'indirection has a cost' is usually the wrong reason to inline and what actually costs you.

We’ve all heard the warning: “Every extra function call adds overhead. Inline it!” In Rust async code, that worry is almost always false.

Look at the size of that arm:

async fn handle_event ( & self , event : Event ) -> Result < () > { match event . kind { EventKind :: Suspend => { // … > 20 lines of app behavior … } // … other arms … } }

The author had hot context in his head when he wrote it and now you’ll see his bias to justify it. And make others justify it too — expecting teammates, contributors, and his future self to accept the cost: lost readability and maintainability. All to satisfy that hot context for no concrete win once it goes cold.

Since the Suspend arm has grown beyond a handful of lines, someone proposes extracting it. You get a clean call site and the logic in a named function:

async fn handle_event ( & self , event : Event ) -> Result < () > { match event . kind { EventKind :: Suspend => self . handle_suspend ( event ). await , // … other arms … } } async fn handle_suspend ( & self , event : Event ) -> Result < () > { // … > 20 lines of app behavior … }

Then someone on the team raises an eyebrow. “Isn’t that an extra function call? Indirection has a cost.” Another member quickly nods.

They’re not wrong in principle. But are they right in practice?

What’s the compiler’s opinion on this? Let’s think through it carefully and measure it.

... continue reading