Go和D广告宣传拥有令人难以置信的快速编译器。 由于语言本身的现代设计,并考虑了并发单通道解析。
了解大部分构建时间浪费在链接阶段。我想知道为什么gcc在小程序上仍然更快。
C
#include <stdio.h>
int main() {
printf("Hello\n");
}
$ time gcc hello.c real 0m0.724s user 0m0.030s sys 0m0.046s
d
惯用
import std.stdio;
void main() {
writeln("Hello\n");
}
$ time dmd hello.d real 0m1.620s user 0m0.047s sys 0m0.015s
黑客攻击
import core.stdc.stdio;
void main() {
printf("Hello\n");
}
$ time dmd hello.d real 0m1.593s user 0m0.061s sys 0m0.000s $ time dmd -c hello.d real 0m1.203s user 0m0.030s sys 0m0.031s
开始
package main
import "fmt"
func main() {
fmt.Println("Hello.")
}
$ time go build hello.go real 0m2.109s user 0m0.016s sys 0m0.031s
爪哇
public class Hello {
public static void main(String[] args) {
System.out.println("Hello.");
}
}
$ time javac Hello.java real 0m1.500s user 0m0.031s sys 0m0.031s
答案 0 :(得分:9)
运行compiler filename
实际上仍然运行链接器并且可以将大量标准库复制到生成的可执行文件中(尤其是损坏D和Go,默认情况下它们的语言运行时静态链接以获得更好的兼容性)。 / p>
鉴于这个琐碎的D hello世界:
import std.stdio;
void main() { writeln("hello world"); }
让我告诉你我电脑上的一些时间:
$ time dmd hello.d
real 0m0.204s
user 0m0.177s
sys 0m0.025s
与使用-c
跳过链接步骤相比,这意味着“编译,不要链接”:
$ time dmd -c hello.d
real 0m0.054s
user 0m0.048s
sys 0m0.006s
将时间缩短到第一次运行的大约1/4 - 在这个小程序中,将近3/4的编译时间实际上是链接。
现在,让我稍微修改一下程序:
import core.stdc.stdio;
void main() { printf("hello world\n"); }
$ time dmd -c hello.d
real 0m0.017s
user 0m0.015s
sys 0m0.001s
使用printf而不是writeln切成两半!我会回到这个。
而且,为了比较,编译+链接:
$ time dmd hello.d
real 0m0.099s
user 0m0.083s
sys 0m0.014s
这让我们知道发生了什么:
链接器占用了大量时间。使用-c
将其从等式中删除。
解析标准库也需要很长时间。仅使用C函数而不是D lib可以将其删除并提供更多苹果到苹果的外观。
但是,使用stdlib对于查看可伸缩性非常重要。
什么D(我认为,Go,但我不太了解它们)的目的是减少编译中型到大型程序的时间。小程序已经很快 - 等待几分之一秒(或者在较慢的计算机上可能只有一两个,我现在在那个计算机上有一个很好的SSD可以加快速度,在旋转硬盘上运行相同的命令磁盘约占时间的两倍!)对于小型构建来说并不是什么大问题。
等待几个分钟进行大型构建是一个问题。如果我们可以将其减少到几秒钟,那将是一场重大胜利。
编译100,000行的时间比编译10的时间更重要。因此初始化时间并不重要。链接时间很重要,但编译器本身没有做太多(链接器是由不同的团队编写的单独程序,尽管在其他地方也有努力改进它)。
因此,构建包括标准库在内的时间是令人印象深刻的。比C hello世界慢(因为C编译器对较小的lib的工作量较少),但是你已经看到了比C ++ hello世界更好的优点,每行更慢,而且每次构建都需要做更多的工作(解析) #includes等。)
良好的编译器基准测试希望将这些问题与测试可扩展性相比较,而不是小程序。虽然如果你运行测试权以确保公平比较,D对小程序也非常非常。