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 virtual construct is an important part of
object-oriented coding and can be very useful in removing the if and switch logic
from an application. Programmers often use virtual and
neglect to remove the switch logic. Note the following:
- The use of a virtual construct (like the use
of a pointer and unlike the use of if statements)
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 a virtual construct
instead of if or switch statements,
you limit optimization opportunities.
- In a non-XPLINK module, because of function overhead, virtual functions
are costlier to execute than straight-line code with if or switch statements.
- 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++ try and
catch blocks,
the compiler creates obstacles to optimization. The compiler cannot
pull common code out of a
try block because it might
trigger an exception that would need to be caught. Similarly, code
cannot be pulled out of a
catch block because:
- The code in a catch block 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
- 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, iostream is
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 of iostream.
- 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 new and delete operators
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 the
new and
delete operators
are costlier to use than variables. Also, before using
new,
you should carefully consider:
- The scope/usage pattern of the variable
- Whether an automatic (local) or global variable is more appropriate