|
In this section... 9.1.1 Pragma Inline9.1.2 Blocks 9.1.3 Arrays 9.1.4 Mod and Rem Operators9.1.5 Constraint Checking |
| Summary of Guidelines from this section |
InlineInline when calling overhead is a significant portion of
the routine's execution time.
procedure Assign (Variable : in out Integer;
Value : in Integer);
pragma Inline (Assign);
...
procedure Assign (Variable : in out Integer;
Value : in Integer) is
begin
Variable := Value;
end Assign; |
The use of pragma Inline does have its disadvantages. It can create
compilation dependencies on the body; i.e., when the specification uses a
pragma Inline, both the specification and corresponding body may need to be
compiled before the specification can be used. As updates are made to the
code, a routine may become more complex (larger) and the continued use of a
pragma Inline may no longer be justified.
Inline may actually
thwart a compiler's attempt to use some other optimization technique such as
register optimization.When a compiler is already doing a good job of selecting routines to be inlined, the pragma may accomplish little, if any, improvement in execution speed.
Language Ref Manual references: 2.8 Pragmas, 6.3 Subprogram Bodies, 6.3.2 Inline Expansion of Subprograms, B Predefined Language Pragmas
...
Initial : Matrix;
begin -- Find_Solution
Initialize_Solution_Matrix:
for Row in Initial'Range(1) loop
for Col in Initial'Range(2) loop
Initial(Row, Col) := Get_Value(Row, Col);
end loop;
end loop Initialize_Solution_Matrix;
Converge_To_The_Solution:
declare
Solution : Matrix := Identity;
Min_Iterations : constant Natural := ...;
begin -- Converge_To_The_Solution
for Iterations in 1 .. Min_Iterations loop
Converge(Solution, Initial);
end loop;
end Converge_To_The_Solution;
...
end Find_Solution; |
Some compilers incur a performance penalty when declarative blocks are introduced. Careful analysis and timing tests by the programmer may identify those declarative blocks that should be removed.
Language Ref Manual references: 5.6 Block Statements
-- M, N are variables which change value at runtime. type Unconstrained is array (Integer range M .. N) of Element; type Zero_Based is array (Integer range 0 .. N - M) of Element; type Constrained_0_Based is array (Integer range 0 .. 9) of Element; |
Although zero based indexing is not as intuitive for humans, it simplifies many of the necessary calculations for indexing into arrays.
Language Ref Manual references: 3.6 Array Types, 3.6.1 Index Constraints and Discrete Ranges
Mod and Rem Operatorsmod and rem operators when
possible.
for I in 0 .. N loop Update(Arr(I mod Modulator)); end loop; |
The following is equivalent, and avoids the mod operator:
J := 0;
for I in 0 .. N loop
Update(Arr(J));
if J = Modulator then
J := 0;
else -- j < Modulator
J := J + 1;
end if;
end loop; |
mod and rem operators are very convenient, but relatively slow. In
isolated cases where performance is of concern, a straightforward mapping to
incremental schemes is possible.
mod and rem operations are
prime candidates for generic utilities. Programmers may then conveniently
apply this optimization when needed.
Get_Response, returns String, then the initialization of the
variable, Input, would require constraint checking. If the variable, Last, is
type Positive, then the assignment inside the loop would require constraint
checking.
...
subtype Name_Index is Positive range 1 .. 32;
subtype Name is String (Name_Index);
...
function Get_Response return Name is separate;
...
begin
...
Find_Last_Period:
declare
-- No Constraint Checking needed for initialization
Input : constant Name := Get_Response;
Last_Period : Name_Index := 1;
begin -- Find_Last_Period
for I in Input'Range loop
if Input(I) = '.' then
-- No Constraint Checking needed in this `tight' loop
Last_Period := I;
end if;
end loop;
... |
Get_Response, may need to check the length of a user supplied string and raise
an exception.Some compilers can do additional optimizations based on the information provided by constrained types. For example, although an unconstrained array does not have a fixed size, it has a maximum size which can be determined from the range of its index. Performance can be improved by limiting this maximum size to a "reasonable" number. Refer to the discussion on unconstrained arrays found in NASA (1992).
Language Ref Manual references: 3.3 Types and Subtypes, 3.3.2 Subtype Declarations, 3.4 Derived Types, 4.5.5 Multiplying Operators