Go1.1性能测试报告(和C差距在10%以内)

<!-- Go1.1性能测试报告(和C差距在10%以内) --> <!-- http://blog.golang.org/2011/06/profiling-go-programs.html -->

最近Go1.1正式发布, 根据官方的说法, Go1.1性能比Go1.0提升基本有30%-40%, 有时更多(当然也有不明显的情况).

Go1.1的详细介绍: Go1.1新特性介绍(语言和库更完善/性能提高约30%).

这里是针对Go1.1和C语言的性能测试: 测试的重点是语言的性能, 当然也会受到标准库性能的影响.

测试环境

补充: i7-3770是4核心8线程.

gccgc版本:

1gcc -v 2gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) 3 4go version 5go version go1.1 linux/amd64

测试结果

1$GOROOT/test/bench/shootout/timing.sh 2fasta -n 25000000 3 gcc -m64 -O2 fasta.c 0.86u 0.00s 0.87r 4 gc fasta 0.85u 0.00s 0.86r 5 gc_B fasta 0.83u 0.00s 0.83r 6 7reverse-complement < output-of-fasta-25000000 8 gcc -m64 -O2 reverse-complement.c 0.45u 0.05s 0.50r 9 gc reverse-complement 0.60u 0.05s 0.65r 10 gc_B reverse-complement 0.55u 0.04s 0.59r 11 12nbody -n 50000000 13 gcc -m64 -O2 nbody.c -lm 5.51u 0.00s 5.52r 14 gc nbody 7.16u 0.00s 7.18r 15 gc_B nbody 7.12u 0.00s 7.14r 16 17binary-tree 15 # too slow to use 20 18 gcc -m64 -O2 binary-tree.c -lm 0.31u 0.00s 0.31r 19 gc binary-tree 1.08u 0.00s 1.07r 20 gc binary-tree-freelist 0.15u 0.00s 0.15r 21 22fannkuch 12 23 gcc -m64 -O2 fannkuch.c 26.45u 0.00s 26.54r 24 gc fannkuch 35.99u 0.00s 36.08r 25 gc fannkuch-parallel 73.40u 0.00s 18.58r 26 gc_B fannkuch 25.18u 0.00s 25.25r 27 28regex-dna 100000 29 gcc -m64 -O2 regex-dna.c -lpcre 0.25u 0.00s 0.26r 30 gc regex-dna 1.65u 0.00s 1.66r 31 gc regex-dna-parallel 1.72u 0.01s 0.67r 32 gc_B regex-dna 1.64u 0.00s 1.65r 33 34spectral-norm 5500 35 gcc -m64 -O2 spectral-norm.c -lm 9.63u 0.00s 9.66r 36 gc spectral-norm 9.63u 0.00s 9.66r 37 gc_B spectral-norm 9.63u 0.00s 9.66r 38 39k-nucleotide 1000000 40 gcc -O2 k-nucleotide.c -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -lglib-2.0 2.62u 0.00s 2.63r 41 gc k-nucleotide 2.69u 0.01s 2.71r 42 gc k-nucleotide-parallel 3.02u 0.00s 0.97r 43 gc_B k-nucleotide 2.66u 0.01s 2.68r 44 45mandelbrot 16000 46 gcc -m64 -O2 mandelbrot.c 20.95u 0.00s 21.01r 47 gc mandelbrot 23.73u 0.00s 23.79r 48 gc_B mandelbrot 23.72u 0.00s 23.79r 49 50meteor 2098 51 gcc -m64 -O2 meteor-contest.c 0.05u 0.00s 0.05r 52 gc meteor-contest 0.06u 0.00s 0.07r 53 gc_B meteor-contest 0.06u 0.00s 0.06r 54 55pidigits 10000 56 gcc -m64 -O2 pidigits.c -lgmp 0.77u 0.00s 0.77r 57 gc pidigits 1.45u 0.01s 1.44r 58 gc_B pidigits 1.45u 0.01s 1.43r 59 60threadring 50000000 61 gcc -m64 -O2 threadring.c -lpthread 12.05u 261.20s 216.36r 62 gc threadring 6.61u 0.00s 6.63r 63 64chameneos 6000000 65 gcc -m64 -O2 chameneosredux.c -lpthread 4.04u 21.08s 4.20r 66 gc chameneosredux 4.97u 0.00s 4.99r

测试结果说明

其中gc_B是开了-B选项, 选项的说明如下:

1go tool 6g -h 2usage: 6g [options] file.go... 3 -+ compiling runtime 4 -% debug non-static initializers 5 -A for bootstrapping, allow 'any' type 6 -B disable bounds checking 7...

应该就是禁用了Go的slice下标越界检测等特性.

测试的结果显示Go的性能已经和C语言已经非常接近了, 有极个别的场景甚至比C还好(binary-tree).

根据$GOROOT/test/bench/shootout/timing.log的数据, gccgo 的优化应该更好一点.

不过目前gccgo的标准库比gc标准库可能要差一些(gccgo1.1还未发布), 因此有些测试性能比gc差一些.

我电脑没有安装gccgo, 因此只有gcc/gc/gc_B三个测试结果.

关于 BenchmarksGame 的测试差异

http://benchmarksgame.alioth.debian.org/u64q/go.php

说明: BenchmarksGame 不是为了测试不同语言的最优性能, 而且为了测试不同语言最自然状态下编写程序的性能. 比如, binary-trees测试就是禁止自己定制专有的缓冲池的, 而C语言的版本则可以随意使用 各种优化手段(基于apr和缓冲池和openmp的并行优化).

BenchmarksGame的测试结果中, 有几个Go的性能很差(已经提交了spectral-norm的优化版本):

1Benchmark Time Memory Code 2fasta 3× 3× ± 3spectral-norm 4× 3× ± 4binary-trees 13× 4× ± 5regex-dna † 26× ± 1/4

补充: BenchmarksGame 测试的是程序实际运行时间, GoBench 是测试的CPU时间. 如果 GoBench 要减少实际时间, 需要充分利用多个CPU的运算资源(Go测试代码对多CPU的性能还有待进一步分析).

补充: BenchmarksGamebinary-trees测试禁止自己定制专有的缓冲池. 因此, 只能寄希望于Go的GC性能改进或新的sync.Cache能尽快发布.

为了方便比较, 在同一台机器上对比了 BenchmarksGameGoBench 的测试结果 .

完整测试代码在: https://bitbucket.org/chai2010/gobench

spectral-norm.go的优化

Go自带的spectral-norm测试性能比BenchmarksGame的性能要低.

我对spectral-norm的代码进行了优化, 优化之后的性能比BenchmarksGame要好一些.

优化前的代码(spectral-norm.go):

1func evalA(i, j int) float64 { return 1 / float64(((i+j)*(i+j+1)/2 + i + 1)) } 2v[i] += evalA(i, j) * u[j]

函数evalA将整数表达式先转换为float64, 然后做了一次倒数运算. 其中倒数的运算有一定冗余.

优化后的代码(chai2010-spectral-norm.go):

1func evalA(i, j int) int { return ((i+j)*(i+j+1)/2 + i + 1) } 2v[i] += u[j] / float64(evalA(i, j))

只在必要的时候才做浮点的转换, 减少了一次倒数的运算.

测试时间由 9.62u 减少到 4.35u, 性能提高约1倍.

完整的对比结果如下:

1./timing.sh 2fasta -n 25000000 3 gcc -m64 -O3 -fomit-frame-pointer -march=native -mfpmath=sse -msse3 alioth-fasta.gcc-2.c 0.96u 0.18s 1.15r 4 gcc -m64 -O3 alioth-fasta.gcc-2.c 0.92u 0.22s 1.15r 5 gcc -m64 -O2 alioth-fasta.gcc-2.c 0.99u 0.15s 1.15r 6 gc alioth-fasta 3.04u 0.00s 3.06r 7 gc_B alioth-fasta 3.03u 0.00s 3.04r 8 gcc -m64 -O3 fasta.c 0.87u 0.00s 0.87r 9 gcc -m64 -O2 fasta.c 0.86u 0.00s 0.87r 10 gc fasta 0.85u 0.00s 0.86r 11 gc_B fasta 0.83u 0.00s 0.83r 12 13spectral-norm 5500 14 g++ -m64 -O3 -march=native -fopenmp -mfpmath=sse -msse2 alioth-spectralnorm.gpp-2.cpp 4.69u 0.00s 0.59r 15 g++ -m64 -O2 -march=native -fopenmp -mfpmath=sse -msse2 alioth-spectralnorm.gpp-2.cpp 4.69u 0.00s 0.59r 16 gc alioth-spectralnorm 6.75u 0.00s 1.67r 17 gc_B alioth-spectralnorm 6.93u 0.00s 1.69r 18 gcc -m64 -O2 spectral-norm.c -lm 9.63u 0.00s 9.66r 19 gc spectral-norm 9.62u 0.00s 9.65r 20 gc_B spectral-norm 9.62u 0.00s 9.66r 21 gc spectral-norm-parallel 9.86u 0.00s 4.91r 22 gc_B spectral-norm-parallel 9.85u 0.00s 4.90r 23 gc chai2010-spectral-norm 4.35u 0.00s 4.36r 24 gc_B chai2010-spectral-norm 4.35u 0.00s 4.36r 25 gc chai2010-spectral-norm-parallel 5.15u 0.00s 2.21r 26 gc_B chai2010-spectral-norm-parallel 4.58u 0.00s 2.22r 27 28binary-tree 15 # too slow to use 20 29 gcc -m64 -O3 -fomit-frame-pointer -march=native -fopenmp -I/usr/include/apr-1 -lapr-1 -lgomp alioth-binarytrees.gcc-7.c -lm 0.21u 0.00s 0.03r 30 gcc -m64 -O3 -fopenmp -I/usr/include/apr-1 -lapr-1 -lgomp alioth-binarytrees.gcc-7.c -lm 0.21u 0.00s 0.03r 31 gcc -m64 -O2 -fopenmp -I/usr/include/apr-1 -lapr-1 -lgomp alioth-binarytrees.gcc-7.c -lm 0.23u 0.00s 0.03r 32 gc alioth-binarytrees 2.16u 0.04s 0.42r 33 gc_B alioth-binarytrees 2.20u 0.04s 0.42r 34 gcc -m64 -O3 binary-tree.c -lm 0.34u 0.00s 0.34r 35 gcc -m64 -O2 binary-tree.c -lm 0.31u 0.00s 0.31r 36 gc binary-tree 1.07u 0.00s 1.07r 37 gc binary-tree-freelist 0.15u 0.00s 0.15r 38 39regex-dna 100000 40 gc alioth-regexdna 2.07u 0.00s 0.64r 41 gc_B alioth-regexdna 2.22u 0.00s 0.71r 42 gcc -m64 -O2 regex-dna.c -lpcre 0.25u 0.00s 0.26r 43 gc regex-dna 1.63u 0.00s 1.64r 44 gc regex-dna-parallel 1.84u 0.00s 0.72r 45 gc_B regex-dna 1.63u 0.00s 1.64r

分析测试的数据, 有以下几个特征(仅针对当前的测试):

  • gcc-O3-O2以及-fomit-frame-pointer等优化参数对性能的优化在20%以内, 可以暂时忽略
  • gc_Bgc的对性能的优化在5%以内, 可以暂时忽略
  • BenchmarksGame 和 GoBench 的C版本测试程序性能很接近(fasta是BenchmarksGame稍好, binary-tree是GoBench稍好)
  • 大部分BenchmarksGame 和 GoBench 的Go版本测试程序性能差距巨大, GoBench要比BenchmarksGame快2~4X.
  • BenchmarksGame 的 spectralnorm 测试性能比 GoBench 的要好(6.75u/9.86u)
  • 经过我手工优化过的 GoBench 的 chai2010-spectral-norm 测试性能比 BenchmarksGame 的要好(5.15/6.75u)
  • BenchmarksGame 的 regexdna 暂时缺少C语言版本的测试数据(没有编译过)
  • GoBench 的 binary-tree-freelist 使用内存池对性能提高约 7X.

综上可以发现 BenchmarksGame 的很多 Go 版本测试程序性能较差(甚至快到10X的差距). 关于 BenchmarksGame 的 Go 测试程序性能低的原因, 大家可以自己去分析代码.

关于regex的测试主要是因为Go的regex标准库比高度优化的C库pcre还是较慢, 目前Go的regex库还有待进一步的优化.

关于pidigits的测试, BenchmarksGame 和 GoBench 基本是一致的: 目前math/biggmp的性能还有2倍的差距.

关于BenchmarksGame和GoBench 的测试差异的很多细节还需要进一步分析. 重点应该是64位系统下多核和并发的性能对比(毕竟Go是多核时代的编程语言).

官方的测试结论

http://go.googlecode.com/hg/test/bench/shootout/timing.log:

1# Sep 26, 2012 2# 64-bit ints, plus significantly better floating-point code. 3# Interesting details: 4# Generally something in the 0-10% slower range, some (binary tree) more 5# Floating-point noticeably faster: 6# nbody -25% 7# mandelbrot -37% relative to Go 1. 8# Other: 9# regex-dna +47%

Go已经和C差距在10%以内, 有特殊场景性能甚至更好.

2013.11.26 补充的官方数据:

1# May 23, 2013 2# Go 1.1, which includes precise GC, new scheduler, faster maps. 3# 20%-ish speedups across many benchmarks. 4# gccgo showing significant improvement (even though it's not yet up to Go 1.1) 5# 6# Standouts: 7# fannkuch, regex-dna, k-nucleotide, threadring, chameneos

在很多测试中, gccgo的性能已经开始超越gc编译的程序的性能.

大数运算的性能比 gmp 还在差 30~40%.

正则比pcre还慢约 5 倍.


https://chai2010.cn/

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )