# When should inline not to be used?

**URL:** <https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804>\
**Category:** New to Julia\
**Created:** [September 26, 2022, 9:43am UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804 "2022-09-26T09:43:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)\
**Post date:** [September 26, 2022, 9:43am UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/1 "2022-09-26T09:43:42Z")

</div>

I found, using `@inline` in some situation can make 10 times more allocation than that without using it. I wonder why this happen?

---

<div class="post-metadata">

**Author:** ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)\
**Post date:** [September 26, 2022, 10:06am UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/2 "2022-09-26T10:06:32Z")

</div>

Hi. An example would make the wheels turn faster 🙂

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [September 26, 2022, 10:25am UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/3 "2022-09-26T10:25:11Z")

</div>

I don’t think that should ever happen. Conversely, when a function is not inlined, it’s also undesirable, I’m scratching my brain to see if it could happen then. In general you can’t easily know if your functions will be inlined, it might change with some small change.

Did you make a mistake, and only saw allocations on first use?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 26, 2022, 11:25am UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/4 "2022-09-26T11:25:23Z")

</div>

Basically never use `@inline` unless you know exactly why you are doing it. There are major potential problems with it, e.g.: [dont @inline large constants by rafaqz · Pull Request #114 · JuliaData/Parsers.jl · GitHub](https://github.com/JuliaData/Parsers.jl/pull/114)

Its mostly useful when you have a chain of small functions you are sure you need to compile away. Otherwise let the compiler decide.

(But also, those problems don’t usually involve allocations - that doesn’t really make sense to me)

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 26, 2022, 12:44pm UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/5 "2022-09-26T12:44:35Z")

</div>

Another example (adapted from a 2016 Github comment by Ian Lance Taylor):

```julia
function internal()
  # Some large and complex function body goes here
end

function external()
  very_rare_case() && internal() # The only place where `internal` is used.
end

```

In this case it wouldn’t make sense to inline `internal` into `external`, even though `internal` isn’t used anywhere else.  
This is because when `internal` isn’t inlined, `internal`’s huge stack frame doesn’t need to be set up except for the rare case when `internal` actually gets called.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [September 26, 2022, 1:12pm UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/6 "2022-09-26T13:12:26Z")

</div>

> Basically never use `@inline` unless you know exactly why you are doing it.

True, _on_ (as opposed to within) function bodies, but new in 1.8:

> The usage within a function body requires at least Julia 1.8.

I guess you shouldn’t bother either, unless you know what you’re doing, I believe I do, and know `@inline` and `@noinline`, for it also:

> The usage within a function body requires at least Julia 1.8.

It feels though _within_ less dangerous for regular users to use.

All this got me curious what C, C++ (and other languages, Rust) do. I knew the compilers inline, but didn’t recall the inline keyword, and new meaning in C++17:

[https://en.cppreference.com/w/cpp/language/inline](https://en.cppreference.com/w/cpp/language/inline)

In Julia it’s about functions, and I think similar. On variables, is new in C++17, Julia doesn’t have anything similar (or need?)?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 26, 2022, 2:38pm UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/7 "2022-09-26T14:38:17Z")

</div>

> [@Palli](#):
>
> On variables, is new in C++17, Julia doesn’t have anything similar (or need?)?

The C++ `inline` isn’t about inlining. Search the page you linked for “inlining”, and the only hit is:

> Because the meaning of the keyword inline for functions came to mean “multiple definitions are permitted” rather than “inlining is preferred”, that meaning was extended to variables.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [September 26, 2022, 3:13pm UTC](https://discourse.julialang.org/t/when-should-inline-not-to-be-used/87804/8 "2022-09-26T15:13:02Z")

</div>

I think you’re wrong about C++ ([EDIT: You might be right about the standard but wrong about some implementations such as Microsoft’s?] the keyword just has more than one meaning there, depending on context), at least I see (and the text there is helpful not just for C+, but also for Julia on the general concept):

> **[Inline Functions (C++)](https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170)**
>
> The C++ inline keyword can be used to suggest inline functions to the compiler.

> ## `inline`, ` __inline`, and `__ forceinline`
> 
> The **`inline`** and **`__inline`** specifiers instruct the compiler to insert a copy of the function body into each place the function is called.
> 
> The insertion, called _inline expansion_ or _inlining_, occurs only if the compiler’s cost-benefit analysis shows it’s worthwhile. Inline expansion minimizes the function-call overhead at the potential cost of larger code size.
> 
> The **`__forceinline`** keyword overrides the cost-benefit analysis and relies on the judgment of the programmer instead.

I think Julia’s inline corresponds to Rust’s #[inline(always)], which isn’t “always”… there, or I think in Julia (in both just a strong suggestion):  
[https://nnethercote.github.io/perf-book/inlining.html](https://nnethercote.github.io/perf-book/inlining.html)

> There are four inline attributes that can be used on Rust functions.
> 
> - **None**. The compiler will decide itself if the function should be inlined. This will depend on the optimization level, the size of the function, etc. If you are not using link-time optimization, functions will never be inlined across crates.
> - **`#[inline]`**. This suggests that the function should be inlined, including across crate boundaries.
> - **`#[inline(always)]`**. This strongly suggests that the function should be inlined, including across crate boundaries.
> - **`#[inline(never)]`**. This strongly suggests that the function should not be inlined.

Inline attributes do not guarantee that a function is inlined or not inlined, but in practice, `#[inline(always)]` will cause inlining in all but the most exceptional cases.

It’s rather amazing what’s possible with this crate (see example Rust/C code): [inline\_c - Rust](https://docs.rs/inline-c/latest/inline_c/) [Somewhat similar to Cxx.jl that I miss in Julia]

> `inline-c` is a small crate that allows a user to write C (including C++) code inside Rust. Both environments are strictly sandboxed: it is non-obvious for a value to cross the boundary. The C code is transformed into a string which is written in a temporary file. This file is then compiled into an object file, that is finally executed. It is possible to run assertions about the execution of the C program.
