字符串和高内存使用率

时间:2014-01-23 14:43:24

标签: delphi

当我在XE4中运行此代码时,应用程序最终使用~800 MB。

为什么不接近100 MB?

使用Ansistring而不是字符串没有区别。

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;

2 个答案:

答案 0 :(得分:11)

XE4中长度为10的字符串使用34字节的内存(请参阅DocWiki)。内容为20字节,#0终结符为2字节,管理数据为12字节。

每个数组条目都是指向那种内存的指针。因此,阵列中的1000万个字符串最终使用380 MB(字符串为340,数组项为40)。

答案 1 :(得分:1)

试试这个

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;