これは Delphi 2009 であるため、Unicode が適用されます。
次のように、バッファから StringList に文字列をロードするコードがいくつかありました。
var Buffer: TBytes; RecStart, RecEnd: PChar; S: string;
FileStream.Read(Buffer[0], Size);
repeat
... find next record RecStart and RecEnd that point into the buffer;
SetString(S, RecStart, RecEnd - RecStart);
MyStringList.Add(S);
until end of buffer
しかし、いくつかの変更中に、ロジックを変更して、最終的に同じレコードを追加することになりましたが、SetString を介してではなく、個別に派生した文字列として、つまり
var SRecord: string;
repeat
SRecord := '';
repeat
SRecord := SRecord + ... processed line from the buffer;
until end of record in the buffer
MyStringList.Add(SRecord);
until end of buffer
私が気付いたのは、StringList のメモリ使用量が 52 MB から約 70 MB に増加したことです。それは30%以上の増加でした。
メモリ使用量を元に戻すには、次のように SetString を使用して文字列変数を作成し、StringList に追加する必要があることがわかりました。
repeat
SRecord := '';
repeat
SRecord := SRecord + ... processed line from the buffer;
until end of record in the buffer
SetString(S, PChar(SRecord), length(SRecord));
MyStringList.Add(S);
until end of buffer
S と SRecord を調べて比較すると、すべてのケースでまったく同じです。ただし、SRecord を MyStringList に追加すると、S を追加するよりも多くのメモリが使用されます。
何が起こっているのか、なぜ SetString がメモリを節約するのか知っている人はいますか?
ファローアップ。まさかとは思いましたが、念のため確認してみました。
ない:
SetLength(SRecord, length(SRecord));
または
Trim(SRecord);
余分なスペースを解放します。そのためには SetString が必要なようです。