为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 C 构建小程序的速度比 Go 或 D 快?

为什么 C 构建小程序的速度比 Go 或 D 快?

Go
慕码人8056858 2021-12-27 10:39:57
Go 和 D 宣称拥有令人难以置信的快速编译器。由于语言本身的现代设计,并考虑到了并发单遍解析。了解大部分构建时间都浪费在链接阶段。我想知道为什么 gcc 在小程序上仍然更快。C#include <stdio.h>    int main() {    printf("Hello\n");}$ time gcc hello.c真实 0m0.724s用户 0m0.030s系统 0m0.046sD惯用语import std.stdio;void main() {    writeln("Hello\n");}$ time dmd hello.d真正的 0m1.620s用户 0m0.047s系统 0m0.015s与黑客import core.stdc.stdio;void main() {    printf("Hello\n");}$ time dmd hello.d真正的 0m1.593s用户 0m0.061s系统 0m0.000s$ time dmd -c hello.d真正的 0m1.203s用户 0m0.030s系统 0m0.031s去package mainimport "fmt"func main() {    fmt.Println("Hello.")}$ time go build hello.go真正的 0m2.109s用户 0m0.016s系统 0m0.031s爪哇public class Hello {    public static void main(String[] args) {        System.out.println("Hello.");    }}$ time javac Hello.java真正的 0m1.500s用户 0m0.031s系统 0m0.031s
查看完整描述

1 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

运行compiler filename实际上仍然运行链接器,并且可能将大量标准库复制到生成的可执行文件中(特别是伤害 D 和 Go,默认情况下它们静态链接它们的语言运行时以获得更好的兼容性)。


鉴于这个微不足道的 D 你好世界:


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 行的时间更重要。所以初始化时间并不重要。链接时间很重要,但编译器本身并没有做太多事情(链接器是由不同团队编写的单独程序,尽管其他地方也在努力改进它)。


因此,D 构建包括标准库所花费的时间是令人印象深刻的地方。比 C hello world 慢(因为 C 编译器对较小的 lib 做的工作较少),但是您已经看到了 C++ hello world 的好处,它每行更慢,并且在每次构建时也往往有更多的工作要做(解析#includes 等)。


一个好的编译器基准测试会比小程序更希望隔离这些问题并测试可扩展性。如果您正确运行测试以确保公平比较,D在小程序上也做得很好。


查看完整回答
反对 回复 2021-12-27
  • 1 回答
  • 0 关注
  • 204 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信