为什么D编译需要这么长时间?
D 即使不是最快的编程语言,也是编译速度最快的编程语言之一,但情况并非总是如此。当 unittest
打开时,事情会变得非常慢。我当前的项目有 6-7 个模块(~2000 LOC),其中每个模块都有包含基准测试的单元测试。以下是我当前项目中的一些数字:
dmd -O -noboundscheck
采用 0m1.287s
dmd -O -release -noboundscheck
采用 0m1.382s
dmd -O -inline -noboundscheck
需要 0m1.499s
dmd -O -inline -release -noboundscheck
需要 0m3.477s
将
-unittest
添加到上述任何一项都会大大增加编译时间:
dmd -O - inline -release -noboundscheck -unittest
需要 0m21.918s
,有时会导致 DMD 崩溃:
time dmd -O t1.d -inline -noboundscheck -version=Double -unittest
需要 0m2.297s
内部错误:../ztc/gdag.c 776
显然,unittest 是有 bug 的,但同时它已经成为我项目的重要组成部分。我想知道这种放缓是正常现象还是正在处理中?我的项目正在不断增长,随着每个新的单元测试,编译所需的时间越来越长。我知道的唯一解决方案是禁用 -release
和 -inline
,但这并不总是可取的。
D is one of the fastest programming languages to compile, if not the fastest, but this isn't always the case. Things become painfully slow when unittest
is turned on. My current project has 6-7 modules (~2000 LOC), with every single one of them having unittests that also contain benchmarks. Here are some numbers from my current project:
dmd -O -noboundscheck
takes 0m1.287s
dmd -O -release -noboundscheck
takes 0m1.382s
dmd -O -inline -noboundscheck
takes 0m1.499s
dmd -O -inline -release -noboundscheck
takes 0m3.477s
adding -unittest
to any one of the above will drastically increase compilation time:
dmd -O -inline -release -noboundscheck -unittest
takes 0m21.918s
and sometimes it crashes DMD:
time dmd -O t1.d -inline -noboundscheck -version=Double -unittest
takes 0m2.297s
Internal error: ../ztc/gdag.c 776
Evidentially, unittest is buggy but at the same time it has become an important part of my project. I would like to know if the slowdown is normal or is it something that's being worked on? My project is growing and with every new unittest the compilation is taking longer and longer. The only solution I know is to disable -release
and -inline
, but that's not always desirable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
DMD 有一个已知的优化问题:长代码块使用 O(n^ 进行优化2)算法,这么长的函数需要很长时间才能编译优化。
尝试将代码拆分为更小的函数,同时您应该获得更好的编译时间。您可以通过使用内联函数轻松地做到这一点:
将其转换为:
这对我有用。
DMD has a known issue with optimisations: long blocks of code optimise with an O(n^2) algorithm, so long functions take a long time to compile with optimisations.
Try splitting your code up into smaller functions and you should get better compile times in the meantime. You can do this quite easily by using inline functions:
Turn this into:
This worked for me.
一个非常微小的性能改进可能是通过
version(unittest) 块
将模板实例化移动到模块范围,例如:对此进行分析,我得到大约
~30msec
速度改进如果我通过 auto x = fooInt(1) 在 5000 个等效的单元测试块中使用别名模板实例,与通过 auto x = 直接在每个单元测试块中实例化它相比foo(1)(这实际上扩展为auto x = foo!int(1)
)。这可能只适用于有大量创建相同模板实例的单元测试的情况。
A very tiny performance improvement could be to move template instantiation to module-scope, via a
version(unittest) block
, e.g.:Profiling this, I get around
~30msec
speed improvement if I use the aliased template instance in 5000 equivalent unittest blocks viaauto x = fooInt(1)
, compared to instantiating it directly in each unittest block viaauto x = foo(1)
(this actually expands toauto x = foo!int(1)
).This will likely only work for cases where you have a lot of unittests that create the same template instance.
我确实替换了大部分通用代码,但它仅将编译时间减少了 4-5 秒。事情变得更糟,我相信编译器可能是问题所在:
time dmd -O -inline -release -noboundscheck -unittest
需要0m30.388s
time dmd -O -inline -release -noboundscheck 需要 0m11.597s
时间 dmd -inline -release -noboundscheck -unittest 需要
0m1.884s
当
-O
、-inline
、-release
和 < code>-unittest都设置好了,编译耗时最长。删除-O
会大大减少编译时间。因此,为了减少单元测试时的编译时间,请删除优化标志。对于正常编译,您可以使用这三个(-inline
、-release
、-unittest
)中的任何一个,没有问题。根据我的经验,这三者的结合导致编译时间第二长,并且在设置-unittest
时也是最长的。I did replace much of my generic code, but it only reduced compilation time by 4-5 seconds. Things have gotten worse, and I believe the compiler is probably the issue:
time dmd -O -inline -release -noboundscheck -unittest
takes0m30.388s
time dmd -O -inline -release -noboundscheck
takes0m11.597s
time dmd -inline -release -noboundscheck -unittest
takes0m1.884s
When
-O
,-inline
,-release
, and-unittest
are all set, compilation takes the longest. Dropping-O
drastically reduces compilation time. Therefore, to reduce compilation time while unittesting, drop the optimization flag(s). For normal compilations, you could use either of the three (-inline
,-release
,-unittest
) with no problem. In my experience, it's the combination of all three that causes compilation to take the second longest, and the longest when-unittest
is set as well.