Mega Code Archive

 
Categories / Delphi / Ide Indy
 

How to save memory in our Delphi programs

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