我正在使用D6 Professional,需要从内存中已有的许多小字符串创建特定格式的文本文件.出于性能原因,我正在考虑使用TMemoryStream来整理文件数据,然后通过TFileStream一次性将其写入磁盘.
但是我有一半被遗忘的记忆(可能是在D6之前的日子里)读取TMemoryStream效率低下的地方,特别是在它达到容量大小之后.我的Delphi(和Windows API)技能不足以检查自己的Classes.pas代码.
(OFFTOPIC)特别是这样的代码:( Classes.pas的第5152行):
NewCapacity:=(NewCapacity +(MemoryDelta - 1))而不是(MemoryDelta - 1);
(/无关)
添加到我的担心是,相关问题的结论,
使用的MemoryStream写出来,希望XML
是不使用内存流,但没有说为什么-无论是由于内存流本身,还是因为在TFileStream的或我足够的缓冲/ O设备驱动程序,或只是相关代码的细节.
感谢任何建议
问候,
PhilW.
普通的TFileStram也可以进行缓冲,这足以优化I/O. 将MemoryStream放在前面只会增加开销.
TFileStream本身不执行由OS处理的缓冲,并且通常足以用于大多数目的.
我的建议是构建一个方法将数据写入流,然后将TSTream参数传递给此方法.这样,您可以轻松地测试不同的选项,而不会影响您的程序.
例如:
Procedure TForm1.StreamMyObjects(aStream : tStream);
begin
aStream.Write( MyString[1], Length( MyString ) * SizeOf( Char ));
aStream.Write( CRLF, Length( CRLF ) * SizeOf( Char ));
aStream.Write( MyOtherString[1], Length( MyOtherString ) * SizeOf( Char ));
aStream.Write( CRLF, Length( CRLF ) * SizeOf( Char ));
end;
Run Code Online (Sandbox Code Playgroud)
在JCL中,如前所述,有一个TJclBufferedStream,然后您可以测试它是否有任何性能优势,这将根据您的写作和您的写作量而有所不同.例如,以下将测试TFileStream和tJCLBufferedStream以查看差异(是的,我知道我错过了TRY/FINALLY):
var
fstm : tFileSTream;
fBufStm : tJCLBufferedStream;
iTicks : Cardinal;
fModes : word; // for SO formatting.
begin
fModes := fmOpenReadWrite or fmCreate or fmShareExclusive;
iTicks := GetTickCount;
fstm := tFilestream.create('test1.txt',fModes);
StreamMyObjects( fStm );
fstm.free;
ShowMessage('TEST1='+IntToSTr(GetTickCount-iTicks));
iTicks := GetTickCount;
fstm := tFilestream.create('test2.txt',fModes);
fBufStm := tJclBufferedStream.create( fStm );
StreamMyObjects( fBufStm );
fBufStm.free;
fstm.free;
ShowMessage('TEST2='+IntToSTr(GetTickCount-iTicks));
end;
Run Code Online (Sandbox Code Playgroud)
在我的测试中,以下例程:
procedure TForm1.StreamMyObjects(aSTream: tStream);
var
St : string;
ix : integer;
begin
for ix := 0 to 10000 do
begin
St := 'This is a string which is written to a stream. ' + IntToStr(ix);
aStream.Write(st[1], Length(st) * SizeOf(Char) );
end;
end;
Run Code Online (Sandbox Code Playgroud)
tFilestream返回47,tJCLBufferedStream返回16.没有循环,时间是微不足道的,这就是为什么你需要测试你的数据...以及你的写作多少.
| 归档时间: |
|
| 查看次数: |
4756 次 |
| 最近记录: |