When to use inline function and when not to use it?

C++CInline

C++ Problem Overview


I know that inline is a hint or request to compiler and its used to avoid function call overheads.

So on what basis one can determine whether a function is a candidate for inlining or not ? In which case one should avoid inlining ?

C++ Solutions


Solution 1 - C++

Avoiding the cost of a function call is only half the story.

do:

  • use inline instead of #define
  • very small functions are good candidates for inline: faster code and smaller executables (more chances to stay in the code cache)
  • the function is small and called very often

don't:

  • large functions: leads to larger executables, which significantly impairs performance regardless of the faster execution that results from the calling overhead
  • inline functions that are I/O bound
  • the function is seldom used
  • constructors and destructors: even when empty, the compiler generates code for them
  • breaking binary compatibility when developing libraries:
    • inline an existing function
    • change an inline function or make an inline function non-inline: prior version of the library call the old implementation

when developing a library, in order to make a class extensible in the future you should:

  • add non-inline virtual destructor even if the body is empty
  • make all constructors non-inline
  • write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value

Remember that the inline keyword is a hint to the compiler: the compiler may decide not to inline a function and it can decide to inline functions that were not marked inline in the first place. I generally avoid marking function inline (apart maybe when writing very very small functions).

About performance, the wise approach is (as always) to profile the application, then eventually inline a set of functions representing a bottleneck.

References:


EDIT: Bjarne Stroustrup, The C++ Programming Language:

> A function can be defined to be inline. For example:

inline int fac(int n)
{
  return (n < 2) ? 1 : n * fac(n-1);
}

> The inline specifier is a hint to the compiler that it should attempt to generate code for a call of fac() inline rather than laying down the code for the function once and then calling through the usual function call mechanism. A clever compiler can generate the constant 720 for a call fac(6). The possibility of mutually recursive inline functions, inline functions that recurse or not depending on input, etc., makes it impossible to guarantee that every call of an inline function is actually inlined. The degree of cleverness of a compiler cannot be legislated, so one compiler might generate 720, another 6 * fac(5), and yet another an un-inlined call fac(6).

> To make inlining possible in the absence of unusually clever compilation and linking facilities, the definition–and not just the declaration–of an inline function must be in scope (§9.2). An inline especifier does not affect the semantics of a function. In particular, an inline function still has a unique address and so has static variables (§7.1.2) of an inline function.

EDIT2: ISO-IEC 14882-1998, 7.1.2 Function specifiers

> A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

Solution 2 - C++

inline has very little to do with optimization. inline is an instruction to the compiler not to produce an error if the function given definition occurs multiple times in the program and a promise that the definition will occur in every translation that it is used and everywhere it does appear it will have exactly the same definition.

Given the above rules, inline is suitable for short functions whose body doesn't necessitate including extra dependencies over what just a declaration would need. Every time the defintion is encountered it must be parsed and code for its body may be generated so it implies some compiler overhead over a function defined only once in a single source file.

A compiler may inline (i.e. replace a call to the function with code that performs that action of that function) any function call that it chooses. It used to be the case that it "obviously" couldn't inline a function that wasn't declared in the same translation unit as the call but with the increasing use of link time optimization even this isn't true now. Equally true is the fact that functions marked inline may not be inlined.

Solution 3 - C++

Telling the compiler to inline a function is an optimization, and the most important rule of optimization is that premature optimization is the root of all evil. Always write clear code (using efficient algorithms), then profile your program and only optimize functions that are taking too long.

If you find a particular function is very short and simple, and it's getting called tens of thousands of times in a tight inner loop, it might be a good candidate.

You might be surprised, though - many C++ compilers will automatically inline small functions for you - and they might ignore your request to inline, too.

Solution 4 - C++

Premature optimization is the root of all evil!

As a rule of thumb I usually inline only "getters" and "setters". Once the code is working and is stable, profiling can show which functions could benefit from inlining.

On the other hand, most modern compilers have quite good optimization algorithms, and will inline what you should have inlined for you.

Reasuming -- write inline one-liner functions, and worry about others later.

Solution 5 - C++

The best way to find out is to profile your program and mark small functions that get called lots of times and burn through CPU cycles that as inline. The keyword here is "small" - once the function call overhead is negligible compared to the time spent in the function, it's pointless to inline them.

The other use I'd suggest is if you've got small functions that get called in performance critical code often enough to make a cache miss relevant, you should probably inline those as well. Again, it's something the profiler should be able to tell you.

Solution 6 - C++

I often use inline functions not as an optimization but to make the code more readable. Sometimes the code itself is shorter and easier to understand than comments, descriptive names etc. For example:

void IncreaseCount() { freeInstancesCnt++; }

The reader immediately knows the complete semantics of the code.

Solution 7 - C++

Inline functions might improve your code performance by eliminating the need to push arguments into the stack. if the function in question is in a critical part of your code you should make the inline not inline decision in the optimization part of your project,

you can read more about inlines in the c++ faq

Solution 8 - C++

The best way would be to examine and compare the generated instructions for inlined and not inlined. However, it is always safe to omit inline. Using inline could lead to trouble you don't want.

Solution 9 - C++

One should use the inline function qualifier only when the function code is small.If the functions are larger you should prefer the normal functions since the saving in memory space is worth the comparatively small sacrifice in execution speed.

Solution 10 - C++

I generally follow a thumb rule where I make a function with 3-4 simple statements as inline. But it is good to remember that it is just a hint to the compiler. The final call to make it inline or not is taken by the compiler only. If there are more than these many statements I will not declare inline as with a stupid compiler it may lead to code bloat.

Solution 11 - C++

When deciding on whether to use inline, I usually keep the following idea in mind: On modern machines memory latency can be a bigger bottleneck than raw calculations. Inlining functions that are called often is known to grow the executable size. Furthermore, such a function could be stored in the CPU's code cache which will decrease the number of cache misses when that code needs to be accessed.

Hence, you have to decide for yourself: Does inlining increase or decrease the size of the generated machine code? How likely is it that calling the function will cause a cache miss? If it is peppered throughout the code, then I would say the likelihood is high. If it is restricted to a single tight loop then the likelihood is hopefully low.

I typically use inlining in the cases I list bellow. However, where you are genuinely concerned about performance, profiling is essential. Furthermore, you might want to check whether the compiler actually takes the hint.

  • Short routines that are called in a tight loop.
  • Very basic accessors (get / set) and wrapper functions.
  • Template code in header files unfortunately automatically obtain the inline hint.
  • Short code that is used like a macro. (E.g. min() / max())
  • Short math routines.

Solution 12 - C++

Also, an inline method has severe side effects when maintaining large projects. When the inline code is changed, all files that use it will be rebuild automatically by the compiler (it it is a good compiler). This could waste a lot of your development time.

When an inline method is transferred to a source file and not inlined any more, the whole project must be rebuilt (at least this has been my experience). And also when methods are converted to inline.

Solution 13 - C++

When you think your code is small enough to be used as inline and remember inline function duplicate your code and paste it were the function is called so it may be good enough to increase your execution time but increased memory consumption also. You can't use inline function when you are using a loop/static variable/recursive/switch/goto/Virtual function. Virtual means wait until runtime and inline means during compilation so they can't be use simultaneously.

Solution 14 - C++

I have read some answers and see that there some stuff missing.

The rule I use is not to use inline, unless I want it to be inline. Looks silly, now explanation.

Compilers are smart enough and short functions always makes inline. And never makes long function as inline, unless programmer said to do that.

>I know that inline is a hint or request to compiler

Actually inline is an order for compiler, it has no choices and after inline keyword makes all code inline. So you can never use inline keyword and compiler will design shortest code.

So when to use inline?

To use if you want to have some code inline. I know only one example, because I use it in only one situation. It is user authentication.

For example I have this function:

inline bool ValidUser(const std::string& username, const std::string& password)
{
    //here it is quite long function
}

No matter how big this function is I want to have it as inline because it makes my software harder to crack.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAshishView Question on Stackoverflow
Solution 1 - C++Gregory PakoszView Answer on Stackoverflow
Solution 2 - C++CB BaileyView Answer on Stackoverflow
Solution 3 - C++dmazzoniView Answer on Stackoverflow
Solution 4 - C++Kornel KisielewiczView Answer on Stackoverflow
Solution 5 - C++Timo GeuschView Answer on Stackoverflow
Solution 6 - C++danatelView Answer on Stackoverflow
Solution 7 - C++AlonView Answer on Stackoverflow
Solution 8 - C++wallykView Answer on Stackoverflow
Solution 9 - C++nitishView Answer on Stackoverflow
Solution 10 - C++NaveenView Answer on Stackoverflow
Solution 11 - C++Rehno LindequeView Answer on Stackoverflow
Solution 12 - C++Thomas MatthewsView Answer on Stackoverflow
Solution 13 - C++sachin pathakView Answer on Stackoverflow
Solution 14 - C++ST3View Answer on Stackoverflow