0%

Go的性能究竟如何?

最近几年Go、RUST等新语言不断推陈出新,令人目不暇接。据说Go与RUST开发出的程序性能非常高,但对于我这种C/C++老鸟来说,对此并不感冒,“再快还能比C快?”这句话一直萦绕在我的心头。

但出于好奇,每次听到有人说Go性能多好多好时,难免都会追问一句“有没有与C进行过对比测试?”,这句并不是想“兑”谁,而是想确认一下网上的传言是否为真。

不幸的是,每当我问这句话时,从来没有得到一个明确答复,也搞不清是他们得出的“Go性能好”是道听途说,还是自己真实的测试结果。

近来时间充裕,一时兴起,心想不如做个简单的Go、C/C++、RUST的性能对比测试吧,验证一下Go的性能到底如何。

简单的测试用例

由于我一直专注在音视频实时通信领域,因此对网络传输的性能特别关心,所以这次测试只验证一下不同语言在传输UDP包时的性能。

为了减少其它因素的影响,测试条件限制如下:

  • 在同一台机子上进行不同语言性能的测试,防止因硬件的不同影响测试结果
  • 服务端只接收不回复,防止服务器干扰测试结果
  • 客户端只发送不接收,每次只发送Hello几个字符
  • 客户端循环发送 1000 0000次,看它的总时长是多少

下面是不同语言编写的测试程序。

C客户端代码

下面是使用C语言实现的客户端代码的主要逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
gettimeofday(&tv0, NULL);
unsigned long lastime = tv0.tv_sec * 1000000000 + tv0.tv_usec;
printf("total: %lu, sec:%lu, nao:%u\n", lastime, tv0.tv_sec, tv0.tv_usec);

//循环 1000 0000 次
for(int a=0; a< 10000000; a++){
n = sendto(sock,
buff_send,
strlen(buff_send),
0, (struct sockaddr *) &addr,
sizeof(addr));
}

gettimeofday(&tv1, NULL);
unsigned long curtime = tv1.tv_sec * 1000000000 + tv1.tv_usec;
printf("total:%lu, sec:%lu, nao:%u\n", curtime, tv1.tv_sec, tv1.tv_usec);
...

从上述代码中可以看到,在for循环执行了 1000 0000 次,每次都调用 sendto 发送UDP数据。

Go客户端代码

Go语言实现的逻辑与C客户端逻辑是类似的,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
...
var lastime int64 = time.Now().UnixNano()
fmt.Printf("lastime: %d\n", lastime)

for a:=0; a < 10000000; a++ {
// 发送数据
_, err = conn.Write([]byte("Hello"))
}

var curtime int64 = time.Now().UnixNano()
fmt.Printf("curtime: %d", curtime)
...

Go的代码非常简单,它与C的区别是其使用Write来发送数据。

RUST客户端代码

RUST语言实现的逻辑也是类似的,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

...
let start = Instant::now();
let mut n = start.elapsed().as_nanos();
std::println!(" elapsed: {}", n);

//loop {
for _i in 1..100001 {
socket.send_to(data.as_bytes(), "127.0.0.1:9998")?;
}

n = start.elapsed().as_nanos();
println!("elapsed : {}", n);
...

测试结果

系统硬件CGoRUST
Mac2.7 GHz Intel Core i5
8 GB DDR3
150秒85秒150 秒
Linux2.7GHz Inter 8 Core i7
8G
17-18秒21-22秒22 秒

结论

刚看到这个结果时,我真是难以至信,Go和RUST的性能竟然与C如此接近。

通过上面的测试我们可以得出以下结论:

  • 新语言 Go 与 RUST 在性能上确实不错,基本上与 C 是接近的,应用层到系统接口之间的层级比较薄
  • 不同的操作系统表现不一样,但通常情况下Go都是在Linux系统下运行,所以应该以Linux系统的测试为准
  • Go、RUST相较C/C++而言,开发效率高很多,如果性能差不多的情况下,采用Go或RUST做服务器开发更有优势

但这次只是一个简单的测试,只能说在发送UDP时,Go、RUST与C性能差别不大,但并不代表在整体性能上Go和RUST已经赶上C/C++性能了。如果想更好的了解Go、RUST与C/C++的差异,应该做更详尽的测试验证。

测试代码

代码地址:https://github.com/andancedu/go_rust_c.git

我的课程

-音视频系统入门

-ffmpeg精讲

-WebRTC入门与实战

-WebRTC高并发流媒体服务器

-从0开始构造直播系统

-OpenCV入门与实战

欢迎关注我的其它发布渠道