Question about value of inlining functions or not.

A function call has a cost, but separating things out into functions is useful for breaking up the code, even for sections only used once.

If I recall correctly, an inline function will be compiled in the body where it was called and thus the finished program won't be making a function call at all.

To me this sounds like a good idea for breaking the source up into easy to handle chunks, even when the code is better without being a function.

My question though is, at what point is it better for the final code to be a function rather than inlined? Is it purely a matter of the size of the final code (including multiple copies for every time a function is called), or is there something else beyond that?

Note, this does not include those cases where a function needs to be a function, such as for recursion.
Last edited on
An inline function saves more than just the cost of the call. Often by inlining the function, it can be optimized better.

The disadvantage as you point out is that the code might be larger. That could actually cause it to run slower. For example, the larger code might cause more paging to occur.

I'll inline very short (one to 5 lines) functions. But most of the code I work with is I/O bound so speed optimizations aren't really necessary. Remember that "premature optimization is the root of all evil." So don't worry about inline vs. out-of-line too much. It's much more important to ensure that your code actually works.
Your compiler can USUALLY inline or not better than the human. Once in a rare while, the human is smarter. Some compilers always ignore the inline keyword and a few compilers have a second over-ride keyword (microsoft uses or used __forceinline or something like that).

You can try it, but don't expect it to help very often. Save this kind of stuff for truly performance critical code.
Register is also funky -- it is also often ignored, and it is also more likely to cause harm than good.
Last edited on
I read recently (in an article about compiling) that the compiler only has the option of inlining code in the header, but not a source file linked by a header. I'm not sure how old that article was, but if it is true, then I would need to write code in the header files just to give the compiler the option of being smarter then me about when to inline.
That is not totally accurate, but if you use the function in many cpp files it may need to be in the header ( i don't recall). Again, the compiler already decides to inline pretty well no matter where the code is located. Putting it in the .h file is when you want to over-ride the compiler's choice and even then, it is just a suggestion to over-ride. Give it a google... there are pages and pages of what can and what cannot be inline (eg, some recursion may not be possible no matter what you tell the compiler) and what is inline by default (small functions inside class header for example are as-if they had the inline keyword) and so much more.

I would not study this, though. If you need something inline and performance enhanced, force it to be inline and check the run-time performance against the standard version of the code. It is really easy to force-inline, either use the keyword if your IDE has one, and if not, drop the function into a standalone file and #include it where you would have called it or turn it into a macro. If it is faster with your forced inline, then you can figure out how to get the compiler to do what you want, backing into it and studying it once you know it is worth studying.
Last edited on
When the compiler sees an inline function, it substitutes the source code directly in place of the function call. Thus there is no function call at all, at runtime.

However, the object code size increases, because at each function call point, the function definition needs to be substituted.

Generally, functions are inlined, when they need to be called often.

Functions can be inlined implicitly or explicitly.

A function defined within the class body is implicitly inlined.
A function defined outside the class body is, by default, not inlined. To inline it, the keyword "inline" must be explicitly specified for the function.

In the interest of keeping the class declaration (interface) and class definition separate, functions should be defined outside the class body.

There is no cutoff limit to decide whether a function should be inlined or not.

Check the tradeoffs and decide accordingly.
What are the trade-offs?

I have a vague idea of there being a cost of some sort for calling a function, as it needs to stop the program, go find the function start point , in some cases transfer values to the new variables, then it gets to resume running code. I also understand that it takes more memory space to have the same function written out multiple times.

What I don't know is the details to consider in choosing to inline or not.
It really comes down to speed. If you are performance tuning, it is much easier to compile the code inline, test it, and time it. Compile the code without inline, time it, test it. Which was faster? Its hard to second guess how many copies of the same code become slower than a function call. This is just like unrolling a loop ... how many repeated statements before the gains are lost? It depends on the system running the code, the compiler that made the code, the CPU and OS types, page size, how its pipelines work, and other variables. And just like a loop, the compiler may have already done the optimization for you, making your efforts in the code pointless.

Last edited on
If you want to make it easier to switch between inlined and non-inlined code, I ran across a little trick a number of years ago. Put all of your potential inlined functions into a new file, say MyClass.inline. Define them as such

1
2
3
4
INLINE void MyClass::foo()
{
// code goes here
}


In your compilation arguments, define INLINE=inline (when inlining) and do not define INLINE if not inlining. Then at the end of MyClass.h, write:

1
2
3
#ifdef INLINE
#include "MyClass.inline"
#endif 


Likewise, at the end of MyClass.cpp, write:

1
2
3
#ifndef INLINE
#include "MyClass.inline"
#endif 


So, when inlining, all of the potential functions get pulled into the .h file prefixed with "inline", and if not, they all get pulled into the .cpp file without a prefix. All you have to do is change a variable in your compilation environment.

> What are the trade-offs?

The tradeoffs are :
1) Speed : When you inline, speed will be faster, because a function call can be avoided. A function call involves copying argument values to the stack, invoking the function and copying the function return value (if any) back to the receiving variable (if any). [Note: move semantics would help avoid copying the return value back to the receiving variable, by simply "moving" (rather than copying) the return value back]

2) Executable file size: When you inline - as I wrote earlier - the compiler simply replaces the function call with the actual function definition in the object code. This happens at every point where the function is called. Therefore file size will increase.

Unless you are writing real-time S/W (where speed is more important), inlining isn't so important.

Many languages don't even support inlining.
> an inline function will be compiled in the body where it was called and thus the finished
> program won't be making a function call at all.

The only binding semantics for an inline function with external linkage is:
it can be defined (identically) in multiple translation units; it must be defined in every translation unit in which it is used; the behavior of the program is as if there is exactly one definition of the function in the entire program.

Inline substitution of the function body at the point of call is a non-binding requirement; as far as inline substitution goes, the typical optimiser does not treat functions marked inline any differently from functions which are not.

Re. inline variables (C++17)
The original intent of the inline keyword was to serve as an indicator to the optimizer that inline substitution of a function is preferred over function call ...

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.
http://en.cppreference.com/w/cpp/language/inline




> My question though is, at what point is it better for the final code to be a function rather than inlined?
> Is it purely a matter of the size of the final code (including multiple copies for every time a function is called),
> or is there something else beyond that?

A good candidate for inline substitution would have the following properties:

a. It is stable (it is unlikely that the implementation of the function would change) -
b. It is called a large number of times during typical program execution.
c. If the function is called from many different places in the code, the inline-substituted code size is comparable to (or at least not much larger than) the code size that would be required for setting up a non-inline call.



> the compiler only has the option of inlining code in the header, but not a source file linked by a header. ...
> I would need to write code in the header files just to give the compiler the option
> of being smarter then me about when to inline.

We can enable link-time code generation; with that cross-translation-unit inline substituion is possible.

Microsoft: -LTCG (enabled by default in 'Release' builds)
https://docs.microsoft.com/en-us/cpp/build/reference/ltcg-link-time-code-generation

GNU / GNU compatible: -flto (caveat: object file sizes and build times shoot up several-fold)
https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Optimize-Options.html#Optimize-Options
Thanks for the replies. Plenty to consider here.
Topic archived. No new replies allowed.