Section 17.3 - Efficiency
In many circumstances it's important to maximize program efficiency, i.e.
your program's execution time and/or memory utilization.
A trivial way to improve efficiency (also called performance)
is to set your compiler options to aggressively optimize your program.
This is an easy way to gain efficiency, since it takes only a few
moments, doesn't change your source code at all, and most compilers
don't turn on their most aggressive optimizations unless you request them.
Before using any other efficiency improvement technique,
measure to see what uses most of the current resources.
Most programs spend most of their time in a very small portion of the
entire program - thus, if you want to improve execution time, you must
spend your time working on those small portions.
It's important to measure, because
programmers often guess incorrectly on where most of the time is being spent.
The most effective efficiency improvement method is
usually changing the algorithm (approach) used to solve the problem.
Jon Bentley has written two good books on general efficiency
improvement techniques, titled
Programs [Bentley 1982]
Pearls [Bentley 1986].
Here are some Ada-specific capabilities for improving efficiency (performance):
Inline specifies that the code for a particular subprogram should be
included immediately inline
rather than performing a normal subprogram call (with its associated overhead).
This can be beneficial for simple subprograms with only a few lines of code.
Optimize lets you specify if you want to optimize for speed
or memory space.
Suppress lets you suppress various run-time checks.
It's best to make sure your program works before suppressing
You may want to only suppress selected checks for selected types or
subprograms, which will let you keep most of Ada's safety features.
Make sure that your program doesn't depend on run-time checks before you
use pragma Suppress.
For example, don't try to handle an exception for
dividing by zero if you might suppress that check - instead,
check if a value is zero before using it as a divisor.
Restrictions restricts the Ada program from using selected Ada capabilities.
In some cases, the Ada compiler may produce faster and/or smaller
code if it knows (via this pragma) that certain capabilities won't
be used, as discussed in the
Rationale part III, D.7.
Pack can be used to decrease the amount of space used by
a compound type (i.e. array or record).
Note, however, that on some machines pragma Pack can slow
the execution of a program down (due to packing and unpacking of bit strings).
- Like all languages except Fortran, when using multi-dimension arrays, vary
the last dimension fastest.
If you want to vary the first dimension fastest (say, if you're
transliterating Fortran code),
use "pragma Convention(Fortran, X)" where X is the array type.
- Types whose sizes are known at compile time (called constrained types)
can be passed around more quickly than types whose sizes are not known
(these are called unconstrained types).
This is because for unconstrained types the Ada compiler must pass around
their bounds as well as their data.
This is especially true when returning an unconstrained type
as a function return value; for technical reasons this is a relatively
expensive operation to perform.
Examples of unconstrained types include type String and any array type
that isn't given an explicit bound at compile time.
Examples of constrained types include Integer, Float, any access type,
fixed-size arrays, and fixed-size records.
Some performance improvement suggestions can be found in
"Ada Programmer Frequently-Asked Questions (FAQ)" file.
Many more suggestions
can be found in the
chapter of the AQ&S guide.
Which of the following techniques is likely to produce the most
significant performance improvement?
- Use pragma Optimize and compiler flags to increase optimization.
- Use pragma Suppress to turn off run-time checks.
- Change the way the problem is solved.
You may also:
David A. Wheeler (firstname.lastname@example.org)