When I run this code in XE4, the application ends up using ~800 MB.
Why not closer to 100 MB ?
Using Ansistring instead of string makes no difference.
const
N = 10000000; // 10 million
M = 10;
var
i,j: integer;
s: string;
X: array of string;
begin
setlength(X,N);
for i:= 1 to N do
begin
s:= '';
for j:= 1 to M do s:= s+chr(65+random(25));
X[i-1]:= s;
end;
showmessage('pause');
end;
An empty String takes 40 bytes—enough memory to fit 20 Java characters.
strings take up more memory, but the memory size is tiny... an integer takes up about 4 bytes for its actual data (some extra for memory pointers depending on how you store it, but string will have that same extra memory as well). A string takes up about a byte per letter (with a minimum of course as .
Strings are stored on the heap area in a separate memory location known as String Constant pool. String constant pool: It is a separate block of memory where all the String variables are held. String str1 = "Hello"; directly, then JVM creates a String object with the given value in a String constant pool.
String[] and List<String> both taking same space in memory to store data. String[] - you need to have all information how much elements get stored in your memory, and it should be not minimum or not maximum space then required space.
A string of length 10 in XE4 uses 34 Bytes of memory (see DocWiki). 20 Bytes for the content, 2 Bytes for the #0 terminator and 12 bytes management data.
Each array entry is a pointer to that kind of memory. Thus those 10 million strings in the array end up using 380 MB (340 for the strings and 40 for the array items) of memory at minimum.
Try this
const MaxString = 15; // you said so
type stringholder = record
strict private
var Cell: string[ MaxString * SizeOf(Char) div SizeOf(AnsiChar) ];
function GetUS: String; // in xe 4 that is a shortcut to UnicodeString actual type
procedure SetUS(const US: string);
public
property Value: string read GetUS write SetUS;
class operator Implicit(const from: string): stringholder; inline;
class operator Implicit(const from: stringholder): string; inline;
end;
function stringholder.GetUS: String;
var i: integer;
begin
i := Ord( Cell[0] );
SetLength( Result, i div (SizeOf(Char) div SizeOf(AnsiChar)) );
if i > 0 then
Move( Cell[1], Result[1], i);
end;
procedure SetUS(const US: string);
var i: integer;
begin
If US = '' then begin
Cell := ''; // constant here, not US itself
Exit;
End;
i := Length(US);
If i > MaxString then raise EInvalidCast.Create('.....'+US);
i := i * SizeOf(Char) div SizeOf(AnsiChar)
Move( US[1], Cell[1], i );
Cell(. 0 .) := AnsiChar(i);
end;
class operator stringholder.Implicit(const from: string): stringholder;
begin
Result.Value := from;
end;
class operator stringholder.Implicit(const from: stringholder): string;
begin
Result := from.Value;
end;
const
N = 10000000; // 10 million
M = 10;
var
i,j: integer;
s: string;
X: array of stringholder;
begin
setlength(X,N);
for i:= 1 to N do
begin
s:= '';
for j:= 1 to M do s:= s+chr(65+random(25));
X(. i-1 .) := s;
end;
showmessage('pause');
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With