Title: How to save memory in our Delphi programs
Question: When a class (or register) is mapped into memory, there is an empty extra space between fields with no information. We can reduce these spaces easily, and the memory requirement of our applications will be less
Answer:
Untitled Document
How to save memory in our Delphi programs
I would like to explain in this article the way Delphi manages classes and
records memory we use in our programs. Maybe it doesn't makes any big difference
in most of our programs, but in some applications can be interesting, especially
because it doesn't cost too much effort.
At first, we will review the basic data types in Delphi, and its (in theory)
size in bytes:
boolean, char and byte = 1 byte
smallInt, word, wordbool = 2 bytes
string, pointers, longint, integer = 4 bytes
Subranges and enumerated types are variables, they depend on their base type.
With all this, if we look to the following class in our source code:
TMyClass = class
private
field1: char;
field2: longint;
field3: boolean;
field4: string;
field5: byte;
field6: integer;
public
procedure proc1;
end;
and we add all the field sizes, we can get the conclusion that each instance
of this class will be 15 bytes long in memory..., simple but not true. The real
size would be 24 (well, 28 if we count the class instance, but this always happens)
bytes, 4 bytes for each field. Why? By default, Delphi, for optimization reasons,
makes all fields start in a memory address multiple of 4: field1 its 1 byte
long, then, field2 must be following field1, but due to this rule, there are
3 empty bytes with no information between field1 and field2, in this way, field2
starts in a memory address multiple of 4. If field2 data type would be byte or
char, it would be placed forthwith field1, because this it wouldn't affect the
alignment of the following fields.
With registers, it happens something similar, but we can avoid this effect
specifying the 'packed' clause, or use the compiler directive {$A-}. We will
lose performance acceding these registers, but we save memory, the question
is when to use it.
But, what can we do with classes?, the solution is very simple: you can change
the declaration order of the fields in the class. I mean, declare all the fields
in groups, depending on its size: all 1 byte sized together, all 2 byte sized
together, and so on.
Using this method, our class will look this way:
TMyClass = class
private
field1: char;
field3: boolean;
field5: byte;
field2: longint;
field4: string;
field6: integer;
public
procedure proc1;
end;
With this organization, the instances of this class will be 16 bytes long,
saving 8 bytes for each instance. Maybe it's not a big save, but if we have
several clases, or bigger classes and we use a lot of instances, the memory
saving can be great, bearing in mind the little effort it costs.
But even be so simple, this process is a great candidate to be implemented
in an IDE expert. Any one want to try?
The spanish version of this article can be found at http://www.ebnoud.com
La version en espa ol de este articulo est en http://www.ebnoud.com