When you write a function or call a library function, consider
the following guidelines:
- Call a function directly, rather than using function pointers.
- Use const arguments in inlined functions
whenever possible. Functions with constant arguments provide more
opportunities for optimization.
- Use the #pragma expected_value preprocessor
directive so that the compiler can optimize for common values used
with a function.
- Use the #pragma isolated_call preprocessor
directive to list functions that have no side effects and do not depend
on side effects.
- Use the restrict keyword for pointers
that can never point to the same memory.
- Use #pragma disjoint within functions for pointers
or reference parameters that can never point to the same memory.
- Declare a nonmember function as static whenever
possible. This can speed up calls to the function and increase the
likelihood that the function will be inlined.
Usually, you should not declare all your virtual
functions inline. If all virtual functions in a class are inline,
the virtual function table and all the virtual function bodies will
be replicated in each compilation unit that uses the class.
When declaring functions, use the const specifier whenever possible.
Fully prototype all functions. A full prototype
gives the compiler and optimizer complete information about the types
of the parameters. As a result, promotions from unwidened types to
widened types are not required, and parameters can be passed in appropriate
registers.
Avoid using unprototyped variable argument functions.
- Design functions so that they have few parameters and
the most frequently used parameters are in the leftmost positions
in the function prototype.
- Avoid passing by value large structures or unions
as function parameters or returning a large structure or a union. Passing such aggregates requires the compiler to copy and store
many values. This is worse in C++ programs in
which class objects are passed by value because a constructor and
destructor are called when the function is called. Instead, pass
or return a pointer to the structure or union, or pass it by reference.
- Pass non-aggregate types such as int and short or small aggregates by value rather than passing by
reference, whenever possible.
- If your function exits by returning the value of another function
with the same parameters that were passed to your function, put the
parameters in the same order in the function prototypes. The compiler
can then branch directly to the other function.
- Use the built-in functions, which include string manipulation,
floating-point, and trigonometric functions, instead of coding your
own. Intrinsic functions require less overhead and are faster than
a function call, and often allow the compiler to perform better optimization.
Many functions from the C++
standard libraries are mapped to optimized built-in functions by the
compiler.
Many functions from string.h and math.h are mapped to optimized
built-in functions by the compiler.
- Selectively mark your functions for inlining, using
the inline keyword. An inlined function requires
less overhead and is generally faster than a function call. The best
candidates for inlining are small functions that are called frequently
from a few places, or functions called with one or more compile-time
constant parameters, especially those that affect if, switch or for statements. You
might also want to put these functions into header files, which allows
automatic inlining across file boundaries even at low optimization
levels. Be sure to inline all functions that only load or store a
value, or use simple operators such as comparison or arithmetic operators.
Large functions and functions that are called rarely are generally
not good candidates for inlining. Neither are medium
size functions that are called from many places.
- Avoid breaking your program into too many small functions. If
you must use small functions, seriously consider using the -qipa compiler option, which can automatically inline such
functions, and uses other techniques for optimizing calls between
functions.
Avoid virtual functions and virtual inheritance
unless required for class extensibility. These language features are
costly in object space and function invocation performance.