delphi - 最优Buffer Stream写入流程

标签 delphi delphi-7

我们有自己的数据流算法,其中包括一些元数据+记录+字段值。

当前我们使用 TStream 并通过 write 向流中添加值。 现在我想知道这次消费操作是否可以通过使用一些技术来加快速度。

编辑:我们只是将数据附加到末尾,而不是移动或查找。

我想到的一些事情是:

  • 不使用Streams buf一些大内存分配的缓冲区来将数据复制到其中,问题是如果我们超出缓冲区大小,那么我们必须重新定位到一些新的内存空间。
  • 使用预先填充#0 到一定大小的流,然后开始添加值。基本原理是 Tstream 必须在每次写入时分配它自己的缓冲区(我不知道它是如何工作的,只是想知道......)

例如,我们将字符串添加到 TStream 中,并以 #0#0#0#1 的形式添加二进制数据。

然后数据通过 TCP 传输,因此不是写入文件。

那么最好的方法是什么?

最佳答案

首先,您假设 TStream是瓶颈。您需要分析您的代码(例如使用 AQTime)来确定瓶颈的真正位置。不要做出假设。

二、什么类型的TStream你真的在用吗? TMemoryStreamTFileStream ?还有别的事吗?不同的流类型以不同的方式处理内存。 TMemoryStream 分配一个内存缓冲区,并在缓冲区填满时将其按预设的字节数增长。 TFileStream另一方面,根本不使用任何内存,它只是直接写入文件并让操作系统处理任何缓冲。

无论您使用哪种类型的流,您可以尝试的一件事是实现您自己的自定义 TStream具有内部固定大小缓冲区和指向真正目的地的指针的类 TStream目的。然后,您可以将自定义类的实例传递给您的算法。让你的类(class)覆盖 TStream::Write()方法将输入数据复制到其缓冲区中直到填满,然后您可以Write()缓冲区到目的地TStream并清除缓冲区。你的算法永远不会知道其中的区别。两者TMemoryStreamTFileStream将从额外的缓冲中受益 - 更少的大写操作意味着更高效的内存分配和文件 I/O。例如:

type
  TMyBufferedStreamWriter = class(TStream)
  private
    fDest: TStream;
    fBuffer: array[0..4095] of Byte;
    fOffset: Cardinal;
  public
    constructor Create(ADest: TStream);
    function Read(var Buffer; Count: Longint): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    procedure FlushBuffer;
  end;

.

uses
  RTLConsts;

constructor TMyBufferedStreamWriter.Create(ADest: TStream);
begin
  fDest := ADest;
end;

function TMyBufferedStreamWriter.Read(var Buffer; Count: Longint): Longint;
begin
  Result := 0;
end;

function TMyBufferedStreamWriter.Write(const Buffer; Count: Longint): Longint;
var
  pBuffer: PByte;
  Num: Cardinal;
begin
  Result := 0;
  pBuffer := PByte(@Buffer);
  while Count > 0 do
  begin
    Num := Min(SizeOf(fBuffer) - fOffset, Cardinal(Count));
    if Num = 0 then FlushBuffer;
    Move(pBuffer^, fBuffer[fOffset], Num);
    Inc(fOffset, Num);
    Inc(pBuffer, Num);
    Dec(Count, Num);
    Inc(Result, Num);
  end;
end;

procedure TMyBufferedStreamWriter.FlushBuffer;
var
  Idx: Cardinal;
  Written: Longint;
begin
  if fOffset = 0 then Exit;
  Idx := 0;
  repeat
    Written := fDest.Write(fBuffer[Idx], fOffset - Idx);
    if Written < 1 then raise EWriteError.CreateRes(@SWriteError);
    Inc(Idx, Written);
  until Idx = fOffset;
  fOffset := 0;
end;

.

Writer := TMyBufferedStreamWriter.Create(RealStreamHere);
try
  ... write data to Writer normally as needed...
  Writer.FlushBuffer;
finally
  Writer.Free;
end;

关于delphi - 最优Buffer Stream写入流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9930552/

相关文章:

DELPHI:如何在循环或案例之外使用 "break"?

delphi - 在公共(public)属性(property)上使用 GetPropInfo

mysql - "Lost connection to MySQL server during query"杀死 Windows 服务

windows - 如何等待多个事件?

delphi - Delphi 7 应用程序中 Aero Glass 的问题

delphi - 中断 HTTP GET 操作

windows - Windows dll 可以检索自己的文件名吗?

delphi - Redmon 和使用 Delphi 捕获标准输入

Delphi - 按换行符分割字符串

delphi - 需要在windows中解析HMONITOR --> deviceName(或deviceName --> HMONITOR)