Code/Rom Size, Ram Size and Speed tips.
See also

Janni's website
Use nested Ifs in stead of long expressions with AND.
Tip from joseLB.
IF (expression1) AND (expression2)...
is much bigger than
IF expression1 then
IF expression2 then ....
In while loops (or repeat loops) it is better to change this
while (expression1) AND (expression2)... do // e.g. while (VarA > VarB) and (VarC < 4) do
begin
...
end;
into this:
while true do
begin
if (not expression1) then break; // e.g. if (VarA <= VarB) then break;
if (not expression2) then break; // e.g. if (VarC >= 4) then break;
...
end;
Use while loops in stead of For loops.
Tip from joseLB.
FOR k := 1 to y do
begin
...
end;
is bigger than
k := 1;
while k <= y do
begin
...
k := k + 1; // do not forget to increment the loop variable
end;
Do not use complex function results.
Using var parameters for complex function results gives smaller code (and maybe smaller ram size) than
making functions that return complex results.
In the PRO version it is possible to make functions with complex results, e.g. strings.
However:
function Test: string[5]; // function returns complex result
begin
Result := ...;
end;
...
MyString := Test;
costs a lot more code than
procedure Test(var S: string[5]); // procedure returns complex result via a var parameter
begin
S := ...;
end;
...
Test(MyString);
The reason is a.o. an extra copying operation if the result is to be used (e.g. in "MyString := Test;") of the return value into the final destination. Also the function itself uses more code.
Additionally it can cost more Ram because an extra "Result" local variable of the result type has to be created. It it can be overlaid then there is of course no extra ram usage.
So, the "old" var parameter method is the cheapest.
Avoid large literal strings in the code.
Place the large literal strings into "constant" in stead of putting them in the code and either
- make your routines work (also) with constant strings as parameters (if possible), or
- copy (see example below) the rom strings to ram if a procedure or function requires a ram string as parameter.
Reason: filling e.g. a string variable with a literal value costs a lot of code, related to the size of the literal value.
// with usage of literal string in code:
TestStr := '123456789012345678901234567890'; // costs 130 bytes of code (P18)
// with usage of string value in constant area:
const StringValue: string[30] = '123456789012345678901234567890'; // costs 31 bytes of rom
...
StrCpyC(TestStr, @StringValue); // costs 24 bytes in code
// additionally there is a (one time only) overhead for StrCopyC (30 bytes).
Use the "with" statement when handling arrays of records.
See also here.
Without "with" usage:
procedure One; // most rom size (364)
var I: byte;
begin
for I := 0 to 19 do
begin
ArrayRec[I].S_ := 'test value';
ArrayRec[I].A_ := 10;
ArrayRec[I].B_ := 20;
ArrayRec[I].C_ := 30;
ArrayRec[I].D_ := 40;
ArrayRec[I].E_ := 50;
ArrayRec[I].F_ := 60;
end;
end;
With "with" usage:
procedure One_with; // average rom size (212) = 42% down
var I: byte;
begin
for I := 0 to 19 do
begin
with ArrayRec[I] do
begin
S_ := 'test value';
A_ := 10;
B_ := 20;
C_ := 30;
D_ := 40;
E_ := 50;
F_ := 60;
end;
end;
end;
Using "pointers":
procedure One_Ptr; // least rom size (200) = 45% down
var Ptr: ^Trec;
I : byte;
begin
Ptr := @ArrayRec;
for I := 0 to 19 do
begin
Ptr^.S_ := 'test value';
Ptr^.A_ := 60;
Ptr^.B_ := 50;
Ptr^.C_ := 60;
Ptr^.D_ := 30;
Ptr^.E_ := 20;
Ptr^.F_ := 10;
inc(Ptr);
end;
end;
Avoid literal string parameters.
The possibility is built in in mP to pass literal strings in stead of string variables as parameter to functions.
e.g.
TestFunction ('testText'); // Can take more ram than the next method, see below
in stead of
MyString := 'testText'; // This method is to be preferred if you have "MyString" available already
TestFunction (MyString); // If you don't have a "Mystring" then both methods are equal in rom/ram usage.
Both methods are the same in codesize and ramsize, but if you have already a string variable available that you can
use to take the content of the literal string (like in the second example above), it is better to use that one.
It saves ram because, when using the first method, the compiler itself creates an extra string variable, fills it with
the literal string, and passes it to then the function.
Avoid string concatenation with '+'.
When doing string concatenation with '+' and extra copy of the destination strings is created
(name of the variable is preceded by "FLOC_" in the listing).
In some cases the extra variable can be overlaid, in other cases not.
var Strng: string[100];
...
Strng := Strng + 'abc'; // <------ here an extra string[100] variable is created
StrCat(Strng, 'abc'); // <------ and here it is not...
none yet.
-------------------------------------------