为什么D编译需要这么长时间?

发布于 2024-12-22 16:22:20 字数 957 浏览 0 评论 0原文

D 即使不是最快的编程语言,也是编译速度最快的编程语言之一,但情况并非总是如此。当 unittest 打开时,事情会变得非常慢。我当前的项目有 6-7 个模块(~2000 LOC),其中每个模块都有包含基准测试的单元测试。以下是我当前项目中的一些数字:

dmd -O -noboundscheck 采用 0m1.287s

dmd -O -release -noboundscheck 采用 0m1.382s

dmd -O -inline -n​​oboundscheck 需要 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三生池水覆流年 2024-12-29 16:22:20

DMD 有一个已知的优化问题:长代码块使用 O(n^ 进行优化2)算法,这么长的函数需要很长时间才能编译优化。

尝试将代码拆分为更小的函数,同时您应该获得更好的编译时间。您可以通过使用内联函数轻松地做到这一点:

void foo()
{
    // lots of code
    // more code
}

将其转换为:

void foo()
{
    void block1()
    {
        // lots of code
    }
    block1();

    void block2()
    {
        // more code
    }
    block2();
}

这对我有用。

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:

void foo()
{
    // lots of code
    // more code
}

Turn this into:

void foo()
{
    void block1()
    {
        // lots of code
    }
    block1();

    void block2()
    {
        // more code
    }
    block2();
}

This worked for me.

写给空气的情书 2024-12-29 16:22:20

一个非常微小的性能改进可能是通过 version(unittest) 块 将模板实例化移动到模块范围,例如:

auto foo(T)(T t) { return t; }

version(unittest) {
    alias foo!int fooInt;
}

unittest {
    auto x = fooInt(1);
}

对此进行分析,我得到大约 ~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.:

auto foo(T)(T t) { return t; }

version(unittest) {
    alias foo!int fooInt;
}

unittest {
    auto x = fooInt(1);
}

Profiling this, I get around ~30msec speed improvement if I use the aliased template instance in 5000 equivalent unittest blocks via auto x = fooInt(1), compared to instantiating it directly in each unittest block via auto x = foo(1) (this actually expands to auto x = foo!int(1)).

This will likely only work for cases where you have a lot of unittests that create the same template instance.

送舟行 2024-12-29 16:22:20

我确实替换了大部分通用代码,但它仅将编译时间减少了 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 takes 0m30.388s

time dmd -O -inline -release -noboundscheck takes 0m11.597s

time dmd -inline -release -noboundscheck -unittest takes 0m1.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文