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