当前位置: 首页 > 知识库问答 >
问题:

为什么Delphi zlib和zip库在64位以下如此缓慢?

宦源
2023-03-14

在对实际应用程序进行基准测试时,我遇到了一个与Delphi附带的zlib和zip库相关的令人惊讶的性能特性。

program zlib_perf;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.Classes, System.Diagnostics, System.Zip;

const
  LoremIpsum =
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod '+
    'tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, '+
    'quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo '+
    'consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse '+
    'cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat '+
    'non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';

function GetTestStream: TStream;
var
  Bytes: TBytes;
begin
  Result := TMemoryStream.Create;
  // fill the stream with 500MB of lorem ipsum
  Bytes := TEncoding.UTF8.GetBytes(LoremIpsum);
  while Result.Size < 500*1024*1024 do
    Result.WriteBuffer(Pointer(Bytes)^, Length(Bytes));
end;

procedure DoTest;
var
  DataStream, ZipStream: TStream;
  Stopwatch: TStopwatch;
  Zip: TZipFile;
begin
  DataStream := GetTestStream;
  try
    ZipStream := TMemoryStream.Create;
    try
      Zip := TZipFile.Create;
      try
        Zip.Open(ZipStream, zmWrite);

        Stopwatch := TStopwatch.StartNew;
        DataStream.Position := 0;
        Zip.Add(DataStream, 'foo');
        Writeln(Stopwatch.ElapsedMilliseconds);
      finally
        Zip.Free;
      end;
    finally
      ZipStream.Free;
    end;
  finally
    DataStream.Free;
  end;
end;

begin
  DoTest;
end.
Compiler  Target  Time (ms)
     XE2   Win32       8586
     XE2   Win64      18908
     XE7   Win32       8583
     XE7   Win64      19304

我使用Explorer shell ZIP功能压缩了同一个文件,我粗略的秒表计时是8秒,所以上面的32位时间似乎是合理的。

由于上面代码使用的压缩算法是zlib(Delphi的邮政编码只支持store和deflate),所以我的信念是Delphi使用的zlib库才是这个问题的根源。为什么delphi的zlib库在64位以下这么慢?

共有1个答案

董权
2023-03-14

如前所述,Delphi ZIP压缩代码位于zlib之上。zlib的Delphi实现是围绕官方zlib C源代码的包装器。C代码被编译为对象,然后与{$link}链接。对于XE7,system.zlib顶部的注释表示使用了zlib 1.2.8。

在zlib代码内部花费时间的明显假设下,对这种行为最合理的解释是64位编译对象导致了性能差。要么是使用的编译器发出了弱代码,要么是使用了不恰当的编译器选项。

于是,我采取了以下步骤:

    null

在用于生成问题中数据的同一台机器上运行的时间为6912毫秒。

然后,我重新编译并省略了/O2选项,并再次循环。这一次的运行时间是20,077毫秒。所以我假设Embarcadero只是忘记了用优化来编译这些对象。

我已经向Enbarcadero的质量门户报告了这个问题:https://Quality.embarcadero.com/browse/rsp-9891

    null

更新

质量门户问题报告此问题在XE8中已修复。

 类似资料:
  • 问题内容: 我希望能够以这种方式一个接一个地获取句子的POS标签: 但是问题是每个句子大约需要一秒钟。还有另一种选择可用于批量执行此操作并加快处理速度。但是,如果我能逐句地做这件事,我的生活会更轻松。 有没有办法更快地做到这一点? 问题答案: 对于NLTK 3.1版,里面,是这样定义的: 因此,每次对first的调用实例化都会花费一些时间,因为它涉及加载pickle文件。 只需调用when是。因此

  • 问题内容: 最近,我一直在对我公司的数据库产品的写入性能进行一些基准测试,并且发现仅切换到64位JVM可以使性能持续提高20-30%。 我不允许详细介绍我们的产品,但基本上它是面向列的数据库,已针对存储日志进行了优化。基准测试包括向其提供几GB的原始日志,并确定分析它们并将其作为结构化数据存储在DB中所需的时间。CPU和I / O的处理非常繁重,尽管很难说是什么比例。 有关设置的一些注意事项: 两

  • 这与 R- 查看具有任何 NA 的所有列名称有关 我比较了data.frame和data.table版本,发现data.table慢了10倍。这与大多数使用data.table的代码相反,后者确实比data.frame版本快得多。 预先设置: 可能是什么原因?

  • 我不知道为什么,为什么我不能使用完整的64位空间例如操作数?和Sign有关吗?或者为什么会有这个限制?(那么,C是否使用前缀对int进行操作(正如前面提到的,前缀只适用于特定指令,而不适用于整个段,它应该是(大小,地址或操作数)默认值,并包含在段描述符中)。 我理解正确吗?

  • 为了好玩,我决定用红宝石编码伊拉托西筛子。只是为了好玩,因为我知道有一个库函数。而且,我认为它会很快。但我发现它并不是,至少在我的ruby 1.9.3中,我的上网本速度快了好几倍,甚至在c中也没有。为什么会这样呢。 库实现: 我在红宝石: 图书馆非常慢。

  • 问题内容: 我正在尝试从Firestore数据库中的python程序中存储64位整数。问题在于,似乎最后一位数字已四舍五入。 当我查看数据库时,它们存储为: 根据文档,支持64位带符号整数。可能是什么问题? 问题答案: 我不确定100%,但是我的猜测是您看到的是JavaScript整数的大小不是64位。它们实际上更像是53位。由于Firebase控制台是使用JavaScript实现的网络应用,因此