Using C++ constructs in performance-critical code
Note: The discussion in this information applies to high-level language
constructs that might seriously degrade the performance of C++ programs.
All other coding discussions in this information apply to both C and C++ programs.
Be aware that in C++, more than in C, certain coding constructs can lead to n-to-1, m-to-1 or even z-to-1 code expansion. You can create well-performing code with these constructs, but you must use them carefully and appropriately, especially when you are writing critical-path or high-frequency code.
When writing performance-critical C++ programs, ensure that you understand why problems might occur and what you can do about them if you use any of the following high-level language constructs:
- Virtual
- The
virtualconstruct is an important part of object-oriented coding and can be very useful in removing theifandswitchlogic from an application. Programmers often usevirtualand neglect to remove theswitchlogic. Note the following:- The use of a
virtualconstruct (like the use of a pointer and unlike the use ofifstatements) prevents the compiler from knowing how that construct is defined, which would provide the compiler with an optimization opportunity. In other words, when you use avirtualconstruct instead ofiforswitchstatements, you limit optimization opportunities. - In a non-XPLINK module, because of function overhead,
virtualfunctions are costlier to execute than straight-line code withiforswitchstatements.
- The use of a
- Exception handling
- When exception handling is available (that is, when you are using
the EXH compiler option), opportunities for both normal optimizations
and for inlining are limited. This is because the compiler must generate
extra code to keep track of execution events and to ensure that all
required objects are caught by the correct routines. When you use the C++
tryandcatchblocks, the compiler creates obstacles to optimization. The compiler cannot pull common code out of atryblock because it might trigger an exception that would need to be caught. Similarly, code cannot be pulled out of acatchblock because:- The code in a
catchblock is triggered far down the call chain, after the exception has occurred - After a catch has occurred, the compiler must ensure that all requested tasks have been executed
You might improve compiler performance by:- Removing dependencies on C++ exception handling from your code
- Compiling with the NOEXH compiler option
- The code in a
- Dynamic casts/Runtime type identification (RTTI)
- A dynamic cast (also known as RTTI) is a coding construct that
delays, until run time, the determination of which code is to be executed.
This limits the potential for optimization. In addition, the process
of actually doing the dynamic cast involves multiple function calls
and large amounts of code. Note: We strongly recommend that RTTI/dynamic casts not be used in performance-critical code. You can often avoid the use of RTTI through careful application design.
- iostream
- As discussed in Using the Standard C++ Library I/O Stream Classes and in Using C and C++ standard streams and redirection,
iostreamis often built upon the standard C I/O library (fprintf,fopen,fclose,fread,fwrite). For I/O performance-critical portions of your application, it is often faster to use the C I/O functions explicitly instead ofiostream.Note: You must be careful if you are mixing the C++ stream classes with the C library. For more information, see Using the Standard C++ Library I/O Stream Classes. - Standard Template Library and other class libraries
- These libraries are very convenient and are often well coded, but you must remember that each use of a class can involve one or more function calls. If you keep this in mind when coding, you can design applications that use these libraries efficiently. For example, you would not initialize all local string variables to the NULL string and then redefine the string on first reference.
- new/delete
- New C++ applications
on z/OS® often
depend heavily on
newanddeleteoperators because they are commonly one of the first things taught in a C++ introductory course, and many courses never explicitly teach that classes can also be automatic (default for local) or global variables.You should be aware that thenewanddeleteoperators are costlier to use than variables. Also, before usingnew, you should carefully consider:- The scope/usage pattern of the variable
- Whether an automatic (local) or global variable is more appropriate
Note: You can ensure that all memory and storage requests are properly optimized by following the instructions given in Improving performance with compiler options and Optimizing memory and storage.