【问题标题】:Does Delphi XE produce faster code than Delphi 2007?Delphi XE 生成的代码是否比 Delphi 2007 更快?
【发布时间】:2011-09-16 08:28:15
【问题描述】:

对于不需要 Unicode 的项目,我主要使用 Delphi 2007。

最近我一直想知道 Delphi XE 因为

  • 每个人都在称赞它;
  • 内置 SVN 支持

不过,我想知道,编译器中是否有任何增强功能可以使 Delphi XE 生成比 Delphi 2007 更快的代码,我说的是:

  • 更好地消除死代码(delphi 2007 还不错,但不能 100% 消除死代码)
  • 循环展开(ala C 的 O3 优化级别)
  • 自动内联短例程
  • 减少多线程代码的开销。

编辑

在这个页面上:http://www.embarcadero.com/products/delphi/whats-new

列出:Improved compiler performance 那么具体改进了什么?

【问题讨论】:

  • 在 XE 中重建的可执行文件应该更快的原因之一是它使用了 Unicode API,因为本机内部 API 是 Unicode(在基于 NT 的 Windows 和更高版本上)。 D2007 调用 Ansi API,每个带有字符串参数的调用都可能导致内部与 Unicode 之间的潜在转换。
  • Win32 字符串 API 调用很少会成为瓶颈。
  • 我最近在 Delphi 中进行了一些数字运算,编写 gold 版本作为 CUDA 代码的基准。恐怕没有太多的unicode:-)。你提出了一个很好的观点,虽然我总是认为 ansistring 更快,因为它使用更少的内存,但忘记了翻译问题。
  • @David 当然,性能差异取决于您实际调用它们的次数。有些应用程序可能会做很多事情,而有些则不会。我只是觉得值得一提。
  • @all,非常感谢您提供了一系列内容丰富的答案

标签: delphi optimization delphi-xe


【解决方案1】:

这里是 embaracadero 的链接

http://www.embarcadero.com/products/delphi/whats-new

在页面下方的一小段

“语言、编译器和库 增强”

他们提到了编译器的改进。这里不多,但他们没有说的也是你的答案。也就是说,如果他们有什么重要的东西,他们可能会吹嘘它。

【讨论】:

    【解决方案2】:

    我没有看到任何证据表明代码生成有任何重大改进。我不知道自 Delphi 5 以来在代码生成方面有什么非常重要的改进。事实上,我从来没有发现我的代码在升级后运行得更快,这可以追溯到 Delphi 2。

    【讨论】:

    • 谢谢大卫,从您从事的项目来看,您可能会比大多数人更早注意到。
    • Delphi 的新版本要好得多,尽管代码生成基本上没有变化。
    • 我只坚持使用 Delphi 2007,因为我在一些项目中使用了 ZEOS 数据库组件,而 ZEOS 的最后一个稳定版本不能理解 unicode。 alpha 版本 7 可以,但我不想在生产代码中使用 alpha 版本。
    • 我很惊讶 ZEOS 在 2011 年 6 月没有生产版本,甚至支持 2008 年发布的 2009 delphi。这就像过时了 3 年。也许是时候放弃 ZEOS 了?
    • @Linas 这不是重点:问题是关于生成的代码,而不是关于库。
    【解决方案3】:

    我对 Delphi XE 编译器的非正式测试表明,在涉及泛型使用的许多情况下,代码生成明显更正确,并且某些编译器内部故障(错误)在 Delphi 2009、2010 时代一直困扰着编译器, 现在已修复。在许多情况下,使用泛型链接到包中的 Delphi 2010 代码在 IDE 中重复重建时,会在编译和链接期间导致损坏的 DCP 文件输出或神秘的编译器内部错误。

    如果是我,我会在发行说明中写下“我们修复了错误”。 (我收回“有史以来最好的”这句话,因为似乎人们认为我的意思是为我当时的雇主做广告,我以前在 Embarcadero 工作过)。我想所有这些都已经解决了进入“性能”一词,其中性能被理解为“正确性”和“可靠地完成工作,没有故障”。

    至于速度,我没有注意到从 Delphi 2009、2010 或 XE 分析代码的任何统计显着差异,就其运行时性能速度而言,也没有编译器的性能,就“它构建项目”而言更快”。

    既然您询问了 Delphi 2007,您应该知道有一个巨大的类型变化(String=AnsiString,到 String=UnicodeString)。对于相同的代码,有些事情会更慢,有些事情会更快,如果你在 2010 年重新编译 2007 年的代码,但对你的代码了解不多,100% 不可能说会发生什么。如果您以前严重依赖 WideString,现在可以改用 UnicodeString,您的代码将变得更快,因为 UnicodeString 的性能比 WideString 的性能好得多。一些 delphi 程序在您的代码中花费大量时间悄悄地(并且几乎不可见)将您的 ansi 数据转换为 unicode 数据,在 win32 内部,例如当您使用 Memo 通用控件时。另一方面,一些过去使用字节大小的字符串,现在将使用字大小的字符串,因此在某些地方内存使用会增加,并且某些操作可能会变慢。对于正确移植的代码(如果您为 2007 年编写它们,您必须对大多数应用程序进行一些更改以使它们在 XE 中构建)最可能的最终结果是,如果有的话,“原始性能”会略有净下降。

    但是,Delphi XE 构建项目,更重要的是在 IDE 中一遍又一遍地进行重建和重建,没有发生任何事故,而且从不崩溃。 Delphi 2007 一直在我身上崩溃。 Delphi 2007 也有数百个令人讨厌的编译器错误,这些错误会让我发疯。编译代码速度甚至不是升级的主要原因,可靠性才是。

    在我一直使用的大型项目中,Delphi 2007、2009 和 2010 通常会在某些复杂包集的第二次或第三次重建时崩溃。在 2009 年和 2010 年,大量使用泛型的软件包特别容易导致 IDE 崩溃。 XE 是稳定的,即使我将它与繁重的泛型代码一起使用时也是如此,这是发行说明可能正在谈论的一种“性能”改进。我称之为“错误修复”。让我们直言不讳。

    (删除最后一段,因为人们认为这是广告)

    【讨论】:

    • 问题寻找 XE 相对于 D2007 的改进。改进的泛型代码生成在这里并不重要。您在回答中只提到了 D2009-XE...
    • “我会在发行说明中写出有史以来最可靠、最可靠、经过良好测试的编译器版本”:只是为了告诉以前版本的客户“嘿,我们一直在开玩笑”?
    • 我将在我的帖子中说明此类从属关系,如果将来我对雇主出售的产品的优点发表任何正面或负面的看法。如果你买或不买,我不会得到额外的钱,而且我不在 RAD 团队,我在其他产品上工作。我也是 Delphi 用户,无论我是否在 Embarcadero 工作,我都会成为 PRO DELPHI。如果我没有受雇于 Embarcadero,我会更强烈地表达我的观点,因为那样的话,我就不必对“严格”的人这么客气了。
    • 投反对票:公司员工为他的公司产品做广告——不管他在公司的工作是什么,都是一种利益冲突。 Guess SO 还应该为此类帖子提供一种“标志”。此外,我看到越来越多的“购买 XE”活动,因为该产品由于新版本的临近而达到“生命终结”状态,我想知道它是自发的,还是营销驱动的努力。
    • 好吧,希望你不要为 Emb 营销工作。 “我们修复了错误”。好的。你的意思是在那之前你卖给我有缺陷的版本,对吧?谢谢,我没有给你假钱作为交换。我知道任何程序都有错误,但是将新版本宣传为“最终我们修复了迄今为止我们卖给你的那些错误”,让我说,有点愚蠢。我很欣赏 Emb 的人们在这里写关于技术解决方案的文章,而不是那些告诉他们的,而是实际的版本,当然,这总是“最好的”。据说连D2005都比以前的版本好……
    【解决方案4】:

    两分,我的两分钱:

    1.对于我们的开源 ORM 框架

    当使用 Delphi 7、Delphi 2007 和 Delphi 2010 编译器运行 our unit tests 时,我发现 Delphi 7 和 Delphi 2007 之间的速度有所提高,但在 Delphi 2007 和 2010 之间并不明显。Delphi 2010 生成的代码被发现是甚至有点慢。我手头没有 Delphi XE 编译器,但我想它与 Delphi 2010 有点相同 - 主要是关于泛型的错误修复,AFAIR。

    当我编写低级 Pascal 代码并使用分析器时,我在 asm 视图 (Alt-F2) 中花费了很多时间。所以我通常会注意到 Delphi 编译器版本之间的差异。

    恕我直言,主要改进确实是方法和函数/过程的 inline 关键字,在 Delphi 2007 中可用,但在 Delphi 7 中不可用。另一个改进是更积极的寄存器重用。

    浮点生成的代码仍然很慢,有时甚至很糟糕(即使不再需要,FWAIT 仍然会产生,内联浮点代码甚至可能是worse than with no inlining

    我们的框架和所有这些测试的有趣之处在于,它确实处理了大量数据,使用自己的低级单元,以非常优化的帕斯卡编码以获得最佳性能。并且提供的单元测试(超过 5,400,000 个单独的测试)适用于真实数据(数值转换或 UTF-8 文本处理),具有许多不同的过程,包括低级转换、文本解析、对象分配、多线程和面向客户端/服务器。所以在这里,编译器生成的代码确实有所不同。

    代码主要在我们的框架内。我们使用我们自己的 RawUTF8 字符串类型,而不是通用字符串。因此,瓶颈既不是VCL也不是Windows API,而只是纯Delphi编译的代码。事实上,我们避免了大多数 API 调用,即使是 UTF-8 编码或数字转换也是如此。

    当然,我用 PUREPASCAL 条件集尝试了这个基准测试,即不在 asm 中运行优化部分,而只依赖“纯帕斯卡”代码。

    2。对于 SynLZ 压缩单元

    另一个关于速度的好实验是编写和分析我们的SynLZ compression unit。通过LZ压缩算法的这种优化实现,压缩比zip快20倍,解压快3倍。事实上,它在压缩比和解压缩速度上与 LZO 竞争,但在压缩方面比 LZO 快得多:SynLZ 能够以与解压缩相同的速率压缩数据。这种对称的实现在压缩领域非常罕见。

    它只涉及整数算术和位逻辑,哈希表的填充和查找,以及内存复制。

    我们编写了一些经过优化的 pascal 代码,然后使用 Delphi 7 和 Delphi 2009 对其进行编译。

    Delphi 2009 生成的代码明显比 Delphi 7 快。生成的代码确实更好,寄存器重用更好。

    通过手动调整的汇编程序分析,我们获得了更好的性能。例如,一个 6 KB 的 XML 文件使用 zip 压缩为 14 MB/s,使用 LZO 压缩为 185 MB/s,使用 Delphi 2009 pascal 版本的 SynLZ 压缩为 184 MB/s,使用我们最终调整的 asm 版本压缩为 256 MB/s SynLZ。

    结论:

    对于涉及整数处理、文本解析或内存的代码生成,我认为 Delphi XE 比 Delphi 7 快,但应该与 Delphi 2007 差不多。内联是主要的新特性,它可以加快很多代码。

    但对于实际应用,速度提升不会很明显。在某些特定情况下大约为 10% 或 20%,而不是更多。算法始终是提高性能的关键。 Delphi 7 已经是一个不错的编译器了。

    对于浮点运算,现在不推荐使用 Delphi 编译器。我希望 64 位编译器中的 SSE 代码会改变这里的结果。

    要直接回答您的问题,在 Delphi 2010 或 XE 中,没有自动内联或自动循环展开,AFAIK。多线程代码中的开销不是编译器的一部分,而是库(FastMM4、引用计数等)的一部分。所以我不认为 Delphi XE 生成的代码比 Delphi 2007 更快。

    【讨论】:

    • 我很想知道在 x64 上生成更好的浮点代码有什么不同。
    • 那么现在 SSE IEEE 兼容吗?
    • 接受了答案,因为分析背景很难调用,尽管此线程中有许多好的答案。
    • @Marco SEE 仍然是 64 位,因此下一个编译器可能会缺乏扩展类型支持。
    • @David 关于 SSE 性能,你可以猜到它对于计算激进的计算会更好。当前Delphi compiler is outperformed by latest Javascript engines 使用动态编译到 SSE:您必须手动编码 SSE 以获得可接受的结果。
    【解决方案5】:

    Delphi 编译器在今天已经非常过时,并且正在被重写。到 XE 的改进看起来是微不足道的,编译器并不能真正利用最新的处理器功能和指令集(它主要停留在 80386 时代,但是对于一些使用手写汇编程序的 RTL 代码来利用更现代的能力)。 XE 编译器可能比以前的版本更可靠(因为 D7 质量变得非常可变),但整体性能改进需要对编译器进行全面检修才能使其进入 21 世纪。 已经进行了,但不知道下一个版本是否只有更新的 64 位编译器,仍然是旧的 32 位编译器,或者 32 位编译器是否也有新的代码库。

    【讨论】:

    • 由于 Intel/AMD 处理器的架构,对于大多数常见的 pascal 代码(包括文本、数据和整数)使用比 386 更新的操作码,速度的提高并不是来自。仅对于浮点计算和大数据处理(如图像处理),像 SSE 这样的新指令集确实有所作为。新的 64 位编译器将有 SSE 进程:这里会有一些真正的变化。
    • 即使是手写 asm 中的 RTL 代码仍然在 80386 区域:它不使用 SSE 或其他任何东西,只调整了 x86 和 x87 asm,并具有优化的对齐内存访问。这里没有 MMX/SSE 的迹象。 ;) 但是当前的 32 位编译器已经做得很好了:比如死代码消除、巧妙的寄存器使用和窥孔优化。
    • @A.Bouchez,很好奇,什么是窥视孔优化?
    • 投反对票的人本可以解释他为什么这样做,只要他能够解释,而且他不仅仅是“德尔福崇拜者”的类别,他试图向每个人发出诅咒,指出他的真实问题神产品。 Embarcadero 本身已决定重写编译器,如果它没有过时,他们就不会这样做。
    • 编译器可能会以多种方式过时。当然,你不能轻易更新到 64 位恕我直言的代码库意味着它也不能轻易更新以支持更新的处理器、指令和新的优化。从头开始重写始终是一项漫长、昂贵且有风险的任务,而且通常当代码变得过时时,您就将其丢弃。 BC++ 编译器在过去几年中也被 VC++ 和 GCC(更不用说英特尔)所取代。
    猜你喜欢
    • 1970-01-01
    • 2016-02-13
    • 2011-07-07
    • 1970-01-01
    • 2011-04-26
    • 2011-12-14
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    相关资源
    最近更新 更多