Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Chapter 12.  Optimization


12.1. Inline Functions

In a sense, this section is not about optimization as much as it is about borrowing an optimization keyword for other means. The inline keyword was introduced to enable the "programmer to help" [Stro1994] direct the compiler in its optimizations. Although many modern compilers pay as much attention to the command-line optimization options as they do to inline specifiers, it still has a role to play in optimizations.

Incidentally, inline is also featured in C as of the C99 standard. It is also available with many compilers as an extension: __inline__ for GCC, __inline for most other Win32 compilers.

12.1.1 Beware Premature Optimization

Premature optimization is something that we are frequently warned against [Stro1997, Dewh2003, Sutt2002, Meye1996, Meye1998], and the use of inline is included in the list of things not to do. There are several reasons why you should avoid premature inlining. First, time spent optimizing before you have identified performance problems with your application represents time not spent on ensuring robustness, flexibility, maintainability, and all the other important aspects of good coding.

Second, if you inline, say, a class method, then you tie the client code of that method to the class's implementation more closely than would be the case if the method's implementation resided in an implementation file not visible to the client code. Any changes you make to the method will require a recompilation of the client code, and in medium-large projects this can prove expensive [Lako1996]. It can also represent a genuine hazard to your popularity in your team.

Third, you cannot set debug breakpoints in inlined code. Compilers and IDDEs help out here, in inhibiting inlining for debug builds, so most of the time this doesn't crop up. But remember in that case that you will be debugging code paths that do not precisely correspond to what's going to happen in release builds.

Finally, indiscriminate use of inline can actually make your code larger, since the compiler may—remember inline is an advisory—insert the body of the function at each call site. Large code, coupled with modern pipelining architectures, where instructions are cached in blocks, can actually cause a reduction in speed.

The best thing to do is to listen to the gurus, profile your code, and make informed adjustments accordingly.

12.1.2 Header-Only Libraries

Notwithstanding the caveats described for its use as an optimization measure, inline also has other uses. These may not have been in the original intent of its inclusion into the language, but we should not discount them.

When one is writing libraries, it is far easier to distribute and use them if they can be reasonably contained in header files only. Even when a function marked inline cannot be inlined, being so marked obliges the compiler/linker to handle any duplicates (C++-98: 3.2;5) without issuing an error message, and usually means that a single definition of the function resides within the link unit.

Hence, inline buys the freedom from having to define a single version of a function and to provide it in an implementation file. This is a great benefit when writing libraries. Furthermore, you'll be in good company when doing so, since it's also used throughout the standard library. Of course, much of the standard library is template code, and so must be inline, and also expected to perform well, so it's not the only reason it's inline. But it's still a factor, and a significant one at that.

Note that when your functions are templates, you do not need to use the inline keyword to guarantee this duplicate coalescence, unless you want your code to be portable to very old compilers (e.g., Visual C++ 4.2).


      Previous section   Next section