Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compilation 为什么D编译要花这么长时间?_Compilation_D - Fatal编程技术网

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

Compilation 为什么D编译要花这么长时间?,compilation,d,Compilation,D,D是编译速度最快的编程语言之一,即使不是最快的,但情况并非总是如此。当打开unittest时,事情会变得非常缓慢。我当前的项目有6-7个模块(~2000loc),每个模块都有单元测试,其中也包含基准测试。以下是我当前项目中的一些数字: dmd-O-noboundschecktakes0m1.287s dmd-O-release-noboundschecktakes0m1.382s dmd-O-inline-noboundschecktakes0m1.499s dmd-O-inline-relea

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

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

-unittest
添加到上述任何一项都将显著增加编译时间:

dmd-O-inline-release-noboundscheck-unittest
takes
0m21.918s

有时它会使DMD崩溃:

time-dmd-O t1.d-inline-noboundscheck-version=Double-unittest
需要
0m2.297s
内部错误:../ztc/gdag.c 776


很明显,unittest是有缺陷的,但同时它已经成为我项目的一个重要部分。我想知道经济放缓是正常的还是正在进行的?我的项目在增长,随着每一个新的单元测试,编译的时间越来越长。我知道的唯一解决方案是禁用
-release
-inline
,但这并不总是可取的

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

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

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

unittest {
    auto x = fooInt(1);
}
如果我通过
auto x=fooInt(1)
在5000个等效的单元测试块中使用别名模板实例,与通过
auto x=foo(1)
在每个单元测试块中直接实例化它相比,我可以在
~30ms
中获得速度提升(这实际上扩展到
auto x=foo!int(1)


这可能只适用于有大量单元测试创建相同模板实例的情况

DMD在优化方面存在一个已知的问题:,因此使用优化编译长函数需要很长时间

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

void foo()
{
    // lots of code
    // more code
}
将此转化为:

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

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

这对我来说很有效。

我确实替换了很多通用代码,但只减少了4-5秒的编译时间。事情变得更糟了,我相信编译器可能是问题所在:

time-dmd-O-inline-release-noboundscheck-unittest需要
0m30.388s

dmd-O-inline-release-noboundscheck的时间
0m11.597s

time-dmd-inline-release-noboundscheck-unittest需要
0m1.884s


-O
-inline
-release
-unittest
都已设置好时,编译时间最长。删除
-O
可以大大缩短编译时间。因此,为了减少单元测试时的编译时间,请删除优化标志。对于正常编译,可以毫无问题地使用这三种编译方式(
-inline
-release
-unittest
)中的任何一种。根据我的经验,正是这三者的结合导致编译时间排在第二位,当设置了
-unittest
时,编译时间排在第二位。

单元测试中有很多模板实例化吗?@CyberShadow是,主要是模板实例化,因为有很多泛型编程。这很可能是原因。尝试将代码的非泛型部分移到模板之外。@CyberShadow没有非泛型代码。@Arlen,我想他的意思是尝试减少泛型代码的数量,只让真正泛型的部分成为泛型。通常,您可以通过从模板中分解出实际上不需要模板化的代码片段来缓解问题。即使你把这样的代码分解成更小的模板,可以更频繁地重用,它也会有帮助。我想你是说嵌套函数?模板或泛型代码似乎不是问题。它确实减少了编译时间,但总的来说这不是问题所在。我重构了代码,只注意到4-6秒的差异。考虑到它只有2k行代码,它仍然非常慢。它与优化有关。我个人在单元测试时不使用
-release
`-发布-摆脱我可能拥有的任何断言,这些断言可能会使我的单元测试在不应该通过的时候通过。@AndrejM。只要使用
-unittest
编译,断言就不会被删除,即使使用
-release
编译也是如此。有趣的是,我不知道这一点。