You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何TFileStream读取速度慢于TMemoryStream?求性能差异原因

为什么TFileStream的读取性能远低于TMemoryStream?

我在工作中发现TFileStream的读取速度慢于TMemoryStream,将TFileStream替换为TMemoryStream后,执行速度瞬间提升。为验证该现象,我编写了测试函数:重复Nr次将同一文件(FileName)加载到TStream中,每次按Siz字节为单位读取至流末尾。

测试函数

1. TFileStream测试函数

因TFileStream无LoadFromFile方法,每次需创建并销毁实例:

function TestFileStream(Nr, Siz: Integer): Double;
var
  sw: TStopWatch;
  Stream: TFileStream;
  I: Integer;
  buffer: TBytes;
begin
  sw := TStopWatch.StartNew;
  System.SetLength(buffer, Siz);
  for I := 0 to Nr - 1 do
    begin
      Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
      try
        Stream.Position := 0;
        while Stream.Position + Siz < Stream.Size do
          Stream.ReadBuffer(buffer, Siz);
      finally
        Stream.Free;
      end;
    end;
  Result := sw.Elapsed.TotalSeconds;
  sw.Stop;
end;

2. TMemoryStream测试函数

每次创建并销毁TMemoryStream实例:

function TestMemoryStream(Nr, Siz: Integer): Double;
var
  sw: TStopWatch;
  Stream: TMemoryStream;
  I: Integer;
  buffer: TBytes;
begin
  sw := TStopWatch.StartNew;
  System.SetLength(buffer, Siz);
  for I := 0 to Nr - 1 do
    begin
      Stream := TMemoryStream.Create;
      try
        Stream.LoadFromFile(FileName);
        Stream.Position := 0;
        while Stream.Position + Siz < Stream.Size do
          Stream.ReadBuffer(buffer, Siz);
      finally
        Stream.Free;
      end;
    end;
  Result := sw.Elapsed.TotalSeconds;
  sw.Stop;
end;

3. TMemoryStream复用测试函数

仅创建一次TMemoryStream实例:

function TestKeepMemoryStream(Nr, Siz: Integer): Double;
var
  sw: TStopWatch;
  Stream: TMemoryStream;
  I: Integer;
  buffer: TBytes;
begin
  sw := TStopWatch.StartNew;
  System.SetLength(buffer, Siz);
  Stream := TMemoryStream.Create;
  try
    for I := 0 to Nr - 1 do
      begin
        Stream.LoadFromFile(FileName);
        Stream.Position := 0;
        while Stream.Position + Siz < Stream.Size do
          Stream.ReadBuffer(buffer, Siz);
      end;
  finally
    Stream.Free;
  end;
  Result := sw.Elapsed.TotalSeconds;
  sw.Stop;
end;

测试结果

Nr = 100, Siz = 1
TFileStream:        27,8980448s
TMemoryStream:      0,1571709s
TMemoryStream Kept: 0,1607682s


Nr = 100, Siz = 16
TFileStream:        1,7674029s
TMemoryStream:      0,044709s
TMemoryStream Kept: 0,0432958s


Nr = 100, Siz = 4096
TFileStream:        0,0427971s
TMemoryStream:      0,0325959s
TMemoryStream Kept: 0,0316288s

我的疑惑

TMemoryStream加载文件时实际使用TFileStream,且ReadBuffer方法继承自TStream,按我的理解两者读取性能不应存在如此大的差异,恳请各位解释该现象的原因。

内容的提问来源于stack exchange,提问作者NihmarIsProgramming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:50:31