tags:

views:

695

answers:

12

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 funtion is a candidate for inlining or not ? In which case one should avoid inlining ?

A: 

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.

Naveen
+2  A: 

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

Alon
+5  A: 

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.

dmazzoni
Indeed, I have my suspicions that certain compilers very sneakily ignore 'inline' completely and only respond to '__inline' or '__force_inline'. I suppose this is to deter abuse!
Rehno Lindeque
Not usually the case. inline is only a hint, but it's a hint most compilers take seriously. You can set the compiler to emit the assembly language along with the object code (`/FAcs` in Visual Studio, `-s` in GCC) to see exactly what it does. In my experience, both those compilers weigh the inline keyword quite heavily.
Crashworks
It's interesting, because in my experience neither g++ nor VC weigh `inline` keyword at all. That is, if you see the function being inlined, and remove `inline` specifier from it, it will still get inlined. If you have any specific examples of the opposite, please share them!
Pavel Minaev
I meant the opposite case more: the compiler is free to inline anything it likes, but it's rare that I see it choose *not* to inline something I told it to `inline`. The typical case I use here is get/set functions (which I inline in the .h rather than define in a .cpp), and 3d vector operations. For some reason, functions like dot/cross product, orthonormalization, etc seem to be just at the threshold where MSVC won't inline them on its own, but will respect the `inline` keyword.
Crashworks
I could be wrong I'm sure. I think I once saw '#define inline' in one of the standard header files, but it could have just been some backward compatibility flag for C. Also it is true that the compiler can inline any function it chooses to.
Rehno Lindeque
how does the `inline` keyword hinder "clear code"? The keyword in "premature optimization" is *premature*, not *optimization. Saying that you should actively *avoid* optimizations is just rubbish. The point of that quote is that you should avoid the optimizations that may not be necessary, and have harmful side effects on the code (such as making it less maintainable). I fail to see how the `inline` keyword is going to make the code less maintainable, or how it can be harmful to add it to a function.
jalf
jalf, sometimes inlining a function will make your code slower, not faster. One example is when the function is called from several different places in your code; if the function is not inlined, then it might still be in the instruction cache when it's called from a different place, and the branch predictor might already be warmed up.There are some patterns that always improve efficiency, so it never hurts to use them. Inlining is not one of them. It usually has no effect on performance at all, it sometimes helps, and sometimes hurts. I stand behind my advice: profile first, then inline.
dmazzoni
Inlining is sometimes negative, but it can also be an *immense* performance gain under the right circumstances. I've measured it: http://assemblyrequired.crashworks.org/2009/01/19/how-slow-are-virtual-functions-really/
Crashworks
+4  A: 

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.

Timo Geusch
A: 

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.

wallyk
+17  A: 

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.

Gregory Pakosz
`inline` is much more than a hint to the compiler. It changes the language rules about multiple definitions. Also, having static data isn't a cast iron reason to avoid inlining a function. The implementation is obliged to allocate a single static object for each function static whether or not the function is declared `inline` or not. Classes are still extensible if they have inline constructors and virtual destructors. And empty brace destructor is the one virtual function that it is _sometimes_ a good idea to leave inline.
Charles Bailey
It's a hint in the sense the function doesn't necessarily ends up inlined (but english isn't my mother tongue). About statics in functions marked `inline`, the result is that the function doesn't get inlined: you pay the price for the call and also each translation unit that includes and calls the function gets its own copy of the code and static variables. The reason for not inlining constructors and destructors when developing a library is binary compatibility with future versions of your library
Gregory Pakosz
@Gregory: Functions with statics can be inlined, its just the actions on the static object which must refer to the same 'global' object; it's required by the standard. W.r.t. binary compatibility I agree with your reasons, but it's a whole other story. The fact that new private data members break binary compatibility usually puts other concerns in the shade. For long lived binary compatibility you often end up having to "pimpl" most interesting objects anyway, rendering the inline discussion irrelevant.
Charles Bailey
@Charles, I edited the answer. I had in mind old compilers treating an un-inlined function as if it had been declared `static`. Indeed conformant compilers will get it right but it was a "better safe than sorry" approach. Still the problem might arise when one misuses `static` on a function so that it becomes private instead of putting it in an anonymous namespace. About pimpl, agreed.
Gregory Pakosz
It's inaccurate to call it a "hint to the compiler". In reality, non-`inline` functions can be inlined if the compiler feels like it. And `inline` functions won't be inlined if the compiler decides not to inline them. As Charles Bailey said, it changes the language rules. Rather than thinking of it as an optimization hint, it is more accurate to think of it as a completely different concept. The `inline` keyword tells the compiler to allow multiple definitions, and nothing else. The "inlining" optimization can be applied to almost any function, whether or not it's marked `inline`.
jalf
I don't see how why my descriptive answer is summed up as "thinking of it as an optimization hint" and I may be blind but what you're saying in your comment about the compiler being fee to decide what gets inline and what not; I wrote it at the end of my answer. And as per http://thefreedictionary.com/hint a "hint" means "a slight indication"
Gregory Pakosz
Yes, but the point is that it is not "a slight indication", but rather a way to get your code to *compile and link successfully where it would otherwise result in an error*. That is the purpose of the `inline` keyword.
jalf
It's just that, when Stroustrup writes "the inline specifier is a hint to the compiler", I'm surprised I'm blamed for quoting him. Anyway, I spent enough time doing my best to back this answer with as much references as possible
Gregory Pakosz
+1  A: 

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.

Kornel Kisielewicz
A: 

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.
Rehno Lindeque
A: 

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.

danatel
+13  A: 

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.

Charles Bailey
+1 Best answer here.
anon
I get the feeling that this is more of a happy coincidence than an intentional feature of C++. The idea is very similar to the 'static' global variables from C. It's a very interesting answer though. I wish they'd just used a keyword like 'internal' to indicate internal linkage.
Rehno Lindeque
+1. @Rehno: I'm not really sure what you're saying. What does linkage have to do with the `inline` keyword? And what is a happy coincidence?
jalf
@jalf: Reading my comment in retrospect I realize it is rather vague and not that well thought out. Defining the same function in multiple files results a linker error which can be countered by declaring the function 'static'. However, 'inline' allows you to do the same thing with subtle differences that they do not actually get internal linkage like 'static' does. I suspect that this is actually more a coincidence because language implementers/designers realized that they'll need to do something special with functions declared in header files and that carried over to 'inline'.
Rehno Lindeque
+1  A: 

A reason not to use inline is that some debuggers won't allow you to set a break point or step into an inlined function.

Rob deFriesse
A: 

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.

Thomas Matthews
That's a different issue. You get the rebuild problem for code that is placed in a header file. Whether it is marked `inline` or not doesn't matter (other than without the `inline` keyword, you'll get linker errors - but the `inline` keyword is not the issue causing excessive rebuilds.
jalf
However, changing an inline method will cause excessive builds versus changing a non-inline method in a shource file.
Thomas Matthews