我一直在试验gc和gccgo,我遇到了一些奇怪的行为。
使用我曾经写过的程序来测试一些定理,我得到了以下结果:(我删除了不必要的信息以便于阅读)
$ time go build -compiler gc -o checkprog_gc checkprog.go (x 3)
go build <...> 0.13s user 0.02s system 100% cpu 0.149 total
go build <...> 0.13s user 0.01s system 99% cpu 0.148 total
go build <...> 0.14s user 0.03s system 100% cpu 0.162 total
--> average: 0.13s user 0.02s system 100% cpu 0.153 total
$ time go build -compiler gccgo -o checkprog_gccgo checkprog.go (x 3)
go build <...> 0.10s user 0.03s system 96% cpu 0.135 total
go build <...> 0.12s user 0.01s system 96% cpu 0.131 total
go build <...> 0.10s user 0.01s system 92% cpu 0.123 total
--> average: 0.11s user 0.02s system 95% cpu 0.130 total
$ strip -s -o checkprog_gc_stripped checkprog_gc
$ strip -s -o checkprog_gccgo_stripped checkprog_gccgo
$ ls -l
1834504 checkprog_gc*
1336992 checkprog_gc_stripped*
35072 checkprog_gccgo*
24192 checkprog_gccgo_stripped*
$ time ./checkprog_gc
./checkprog_gc 6.68s user 0.01s system 100% cpu 6.674 total
./checkprog_gc 6.75s user 0.01s system 100% cpu 6.741 total
./checkprog_gc 6.66s user 0.00s system 100% cpu 6.643 total
--> average: 6.70s user 0.01s system 100% cpu 6.686 total
$ time ./checkprog_gccgo
./checkprog_gccgo 10.95s user 0.02s system 100% cpu 10.949 total
./checkprog_gccgo 10.98s user 0.01s system 100% cpu 10.964 total
./checkprog_gccgo 10.94s user 0.01s system 100% cpu 10.929 total
--> average 10.96s user 0.01s system 100% cpu 10.947 total我可以看到以下模式:
gccgo构建的二进制文件的大小要小得多(剥离无助于改变这种差异)gc构建的二进制文件执行起来更快gccgo构建比用gc构建要花费更多的时间。我还测试了其他一些go程序(虽然不是很广泛),它们都表现出了相同的行为。
这似乎与这个答案的说法相矛盾:
简而言之:gccgo:更多的优化,更多的处理器.
我认为更多的优化意味着更快的二进制文件,同时需要更多的时间来编译.
这三种模式的原因是什么?
发布于 2014-11-21 18:31:47
有很多不同的地方--布兰德菲茨在2014年5月的一次演讲中谈到了其中的一些
gccgo可以生成一个在libgo中动态链接的二进制文件,这使得输出更小,但意味着要在目标机器上安装相关的库。没有cgo的Go二进制文件没有这个要求。gccgo进行更低级别的优化,因为它可以使用gcc的代码生成器和优化器。gccgo编写一些数据压缩代码,运行速度明显快于gc。同样的优化使得编译器速度变慢:它正在做更多的工作。gccgo支持gcc所做的目标处理器,因此它是获得某些体系结构(如SPARC、ARMv8 (64位)或POWER )的唯一方法。(规范使用它来编译用于arm64和ppc64的Juju服务编排工具。)gccgo和gc都支持ARMv7 (32位),但根据bradfitz的talk,gc并不能生成效率最高的ARM代码。gc才有某些优化。new(T)的返回值没有转义,它可能不会进行堆分配。)这减少了需要运行垃圾收集的频率。.s汇编程序文件仅由gc链接,因此gccgo默认不使用英特尔硬件CRC32C之类的东西(您必须为gccgo提供一个专门的实现)。
gc首先实现了新的语言特性,通常比最新的gccgo稍早几个版本。发布于 2014-11-21 18:13:02
大小是不同的,因为gc提供静态二进制文件和到libgo的gccgo链接。这意味着整个运行时的代码(调度器、垃圾收集器、映射、通道)不是由gccgo创建的最终二进制文件。
当然,编译的速度将有利于gc。GC是在考虑编译速度的情况下构建的。它通常也会产生较少的优化代码,并且需要执行的工作也较少。
现在说说为什么gc更快了。事实是,他们中的任何一个都不会比其他人快。例如,尝试md5一个文件和GCCGO将是一个数量级更快。尝试实现一些有很多渠道的东西,gc肯定会赢。你不可能总是提前判断哪个会成功。GC往往具有更高效的并发性,而gccgo则更擅长数学。然而,这是您需要在一个案例的基础上测试的东西。最好使用go测试的基准测试系统,而不是时间。
https://stackoverflow.com/questions/27067112
复制相似问题