Delphi:如何组织源代码以提高编译器性能?

时间:2009-05-28 12:17:09

标签: delphi optimization compiler-construction

我正在开发一个具有相当多依赖性的大型delphi 6项目。编译整个项目需要几分钟的时间。经过一些更改后重新编译有时会更长,以便更快地终止Delphi,擦除所有dcu文件并重新编译所有内容。

有没有人知道识别的方法,是什么让编译器变慢?有关如何组织代码以提高编译器性能的任何提示吗?

我已经尝试过以下事项:

  • 明确包含dpr中的大多数单位,而不是依赖于搜索路径:它没有改进任何内容。
  • 使用命令行编译器dcc32:它不会更快。
  • 试着看看编译器做了什么(使用来自SysInternals的ProcessExplorer):显然它大部分时间运行一个名为'KibitzGetOverloads'的函数。但我对这些信息无能为力......

编辑,答案摘要至今:

在我的案例中效果最好的答案:

  • cnpack中的“清除未使用的单位参考”功能。它几乎自动清理了超过1000个引用,使“冷”编译速度快了两倍。 (“冷”编译=在编译之前擦除所有dcu文件)。 它从编译器获取引用列表。因此,如果您有一些{$ IFDEF},请检查您的所有配置是否仍然可以编译。

接下来我想尝试一下:

  • 手动重构单位引用(最终使用抽象类) 但它还有很多工作要做,因为我首先要确定问题所在。一些可能有用的工具:
    • GExperts将项目依赖项浏览器添加到delphi IDE(但遗憾的是它无法显示每个分支的大小)
    • Delphi Unit Dependency Viewer V1.0做同样的事情,但没有Delphi。它可以计算一些简单的统计数据(哪些单位被引用最多,......)
    • Icarusa link中引用了其中一个答案。

在我的案例中没有改变任何事情的事情:

  • 将我的程序和所有组件中的每个文件放在一个没有子文件夹的文件夹中。
  • 对磁盘进行碎片整理(我尝试使用ramdisk)
  • 使用ramdisk作为代码源和输出文件夹。
  • 关闭实时扫描防病毒软件
  • 列出dpr文件中的所有单元,而不是依赖于搜索路径。
  • 使用命令行编译器dcc32或ecc32。

不适用于我案件的事情:

  • 避免依赖网络共享。
  • 使用DelphiSpeedUp,因为我已经拥有它。
  • 为所有dcu使用单个文件夹(我总是这样做)

我没试过的事情:

  • 升级到另一个Delphi版本。
  • 使用dcc32speed.exe
  • 使用固态硬盘(我没试过,但我尝试使用ramdisk,我把所有的源代码都放了。但也许我应该在ramdisk上安装delphi)。

16 个答案:

答案 0 :(得分:11)

可能会降低编译器速度的一些事情

    {li> uses子句中的冗余单元。有关CnPack。的链接,请参见this question
  • 未明确向项目文件添加单位。你似乎已经涵盖了这一点。
  • 更改了编译器设置,最值得注意的是include TDD32 info

尝试删除uses子句中未使用的单位,看看它是否有所作为。

答案 1 :(得分:9)

使用Delphi 7和2009,上周我通过近2分钟进行编译,另外45秒来点击f9并将我的应用程序的主要形式编译并运行20秒。这件事让我疯狂了大约6个月,我尝试的任何东西似乎都没有用。使用来自SysInternals的filemon,我意识到编译器所需的每个单元(主要是组件)都在搜索路径中的每个文件夹中进行搜索,是的,这会产生大量的FileOpen,FileExists和FileNotFound等。我做的是,每个DCU,DFM,RES等来自组件全部在一个文件夹中,并且在搜索路径中只有这个文件夹,以及项目所需的其他几个文件夹;结果太棒了。修复之前的其他问题是调试。每次F7需要almos 40秒,在调试时按F8键,这也已修复。希望这些信息可以帮到你。委内瑞拉Isla de Margarita的问候。请原谅我的英文,如果有任何错误;)

答案 2 :(得分:8)

检查搜索路径中是否存在本地计算机上没有的路径。

即。不要链接到网络共享上的二进制文件,并检查搜索路径是否未检查任何网络共享。

答案 3 :(得分:5)

您可以尝试DelphiSpeedUp,看看它是否有所作为。它不会加速命令行编译,但它声称有一些IDE编译的加速。

答案 4 :(得分:4)

我没有看到编译器随着时间的推移变慢,但是自从我们使用Delphi 6以来已经很长时间了。

  1. 在Delphi社区中似乎普遍认为,如果您不想升级到最新最好的(Delphi 2007或2009),那么Delphi 7是最好/最快/最稳定的。您可以考虑升级。
  2. KibitzGetOverloads听起来像是来自kibitz编译器的东西 - “背景”编译器,它为您提供代码完成,背景错误突出显示,代码工具提示等。听起来您最好检查命令的调用堆栈 - 行编译器,而不是IDE;你会得到更多帮助。
  3. 删除DCU后,我从未发现编译速度更快。 DCU可以使构建增量,因此更快。如果您在删除所有DCU后看到更快的编译,请检查您的硬件。你最近搞砸了你的硬盘吗?您在驱动器上有多少可用空间?

答案 5 :(得分:4)

  1. 您是否设置了一个文件夹来获取DCU。如果没有,他们将分散在各地。
  2. 将所有单元及其隐式调用的单元(库路径中已安装的组件除外)放入dpr中。为了确保你没有错过一些,清空你的搜索路径,它仍然应该编译。
  3. 缩小搜索路径后,您可以尝试通过将组件安装到较少的文件夹来减少库路径。

答案 6 :(得分:3)

虽然只与你的确切问题部分相关,但我听说使用固态硬盘大大增加了Delphi的编译时间--Nick Hodges几周前在Delphi Podcast上说过这个问题。 布赖恩

答案 7 :(得分:2)

答案 8 :(得分:2)

我们遇到了相同(或类似)的问题。 我的包的编译时间约为12分钟。 在更改之后,现在我们已经移动到32 sg。

经过多次测试后,我们发现“有问题的情况”如下: 在一个包中:

  • A单元在同一个包中使用大量单位:U1,U2,U3,U4,... U100(接口的使用)。这是集中所有初始化工作的重要单元。

  • 包裹的所有单位,U1,U2,U3,..,U100使用单位A (使用实施)

这个“循环引用”不会产生编译错误,因为USES不同,但导致编译时间很长。

解: 消除 A单位中对每个单位U1,U2,U3,....,U100的引用。

现在,一个单位使用大量单位:U1,U2,....,U100,但单位U1,U2,...,U100,不使用单位甲

在此更改之后,编译时间大幅缩短。

如果您遇到类似情况,可以尝试一下。

我的英语不好的借口。

问候。


Neftalí-GermánEstévez -

答案 9 :(得分:2)

我有同样的问题,我可以提出(2)影响我的原因。

  1. 循环引用。这位绅士说一个是正确的。我会有一些可以快速编译的LARGE项目,以及编译速度慢的SMALL项目。在我重新构造代码之前无法理解它,然后我获得了更快的编译速度。很多小单位。构建单片单元很容易。但是,它有许多处罚。

  2. 我已经听过1000次了,在用户可能正在使用的慢速机器上进行开发。嘿,这是测试部门的。我不能浪费时间编译,Delphi加载速度,软件包等。我出去买了一台“GAMERS”电脑(WOW)和固态硬盘(如前所述),12GB RAM,OVERCLOCKED“i7”Intel芯片,三重视频卡(链接),全部在Vista64上(一旦最终运行所有已安装的部件,Vista也不错)。把它全部设置起来真是太痛苦了。但是,我不再在我的电脑上等了。纯粹的编译速度,加载速度,加上一台全新的机器,没有在过去两年中安装在最后一个上的所有垃圾。我甚至卸载了DelphiSpeedUp。不需要它。而且我不需要关闭AntiVirus,因为我也做了那个,并因互联网垃圾而受到惩罚。所以AntiVirus继续使用。纯粹而简单,得到一台BALLS OUT机器。您的时间比在新计算机上花费的时间更多。

答案 10 :(得分:2)

请参阅this

我使用VCL.NET代码库进行了测试并且工作....不知道它是否仍然适用于D2009,但它在D2006.net上运行

答案 11 :(得分:1)

尝试安装ram磁盘并将dcu输出路径设置为指向那里。这使我在DelphiSpeedUp之上使用Delphi 2007的编译时间减少了一半。

答案 12 :(得分:1)

编译器只会编译已更改的单元。如果您更改了接口部分中的代码,则会编译依赖于已更改单元的所有单元。如果仅更改了实现部分中的代码,则编译将仅包含该单元,但可能链接所有模块。预先设想好的接口设计但如果重构代码以限制对实现的更改,则编译时间可能会减少。我不知道多少钱。在Delphi 7“使用Delphi”中的多个和间接单元引用下的Delphi帮助文件中提到了这一事实。

答案 13 :(得分:1)

由于我没有获得50点声望点,我无法回复我的BALLS OUT帖子。所以我必须在这里开始一个新的订单项。我买了这台机器来处理非常大的Photoshop文件,我还在Inventor和3DStudio MAX中做了很多3D建模。这就是我买新机器的原因。但是......由于它,我肯定会在我的Delphi使用方面获得巨大的推动。我的工资成本超过我在新机器上花费的额外2K,而不是购买一些基本的戴尔(这可能对Delphi来说很好)。所以我可能收到的任何BOOST都是奖金。如果你像我一样每天都在做这项工作,那么你遇到的任何延迟都会成为真正的问题。它使用Photoshop,Autodesk产品和DELPHI为我做了什么。所以我会再说一次,一台新的BALLS OUT机器,将改善你的表现。这家伙问他能做些什么来提高编译性能。所以,我发表了自己的意见。

P.S。将Delphi和您的项目放在固态硬盘上,您将看到大幅提升。

答案 14 :(得分:0)

  • 不要在网络驱动器上编译。寻求时间非常糟糕。
  • 考虑将你的dcu(“单位输出”目录指向ramdrive。
  • 限制包含/单元目录的数量。
  • 尽量避免编译器仍然接受的次要循环引用,特别是对于大型单元(例如,为OPF生成的ORM单元)。它可能导致大型单元被编译两次。 (Delphi是否允许较小的相互通告,或者仅仅是FPC功能?)

我从未尝试过,但在中央.dpr中使用完整/相对路径对所有文件进行硬编码也可能有帮助(脚本重新生成/更新?)。 (你在上面提到过,但它是用'\ path \ yyy'表示法中的路径xx吗?)。

其他远射:

  • 使用Kylix(Linux下的文件/目录I / O在我的经验中显着提高(尽管这来自FPC经验))。也许我们需要一个反向的交叉kylix: - )
  • 使用单独的(windows)构建计算机,并通过注册表调整NTFS以减少“安全”。 (你不关心,因为一切都是一个修订系统开始)。 Afaik这些选项只能在所有文件系统上全局完成,因此是单独的系统。也可以投入raid阵列或Raptor。
  • 忘记固态。不错的热门话题,但是高写入比率最终会杀死它(当它变得更加饱满并且不能再进行最佳分配时,它的生命和性能都会消失),而你需要昂贵的英特尔才能在RAID中击败两个75美元的高清。

P.S。对不起FPC参考。我做了两件事,有时我不知道什么属于什么。

答案 15 :(得分:0)

我所做的总是确保库路径中的目录很少,以及大多数组件和静态代码。我还确保库路径中没有源代码,只有.dcu / .res等。只有browsepath有源代码,特殊情况通过项目的searchpath处理。

在任何情况下限制你编译的内容。