我是靠谱客的博主 细腻路人,这篇文章主要介绍cgo对go的性能影响cgo对go的性能影响,现在分享给大家,希望可以做个参考。

cgo对go的性能影响

概述
做go封装给python和perl进行使用的时候,使用cgo->swig->python、perl流程,对整个流程的性能进行了粗略的性能比较。(在deepin环境进行的测试)

cgo代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package main //注意必须是main包 // #include <stdio.h> import "C" import ( "fmt" "io/ioutil" "net/http" ) //export hello func hello() { fmt.Println("hello biz-binary") } //export hello2 func hello2() *C.char { return C.CString("hello biz-binary") } //export add func add(a, b int) int { return a + b } //export HttpGet func HttpGet(url *C.char) *C.char { res, err := http.Get(C.GoString(url)) if err != nil { return nil } var resByte []byte resByte, _ = ioutil.ReadAll(res.Body) return C.CString(string(resByte)) } func main() { //不能省略 }

两个,测试,一是从python进入go的栈并退出整个流程的耗时,二是通过cgo发送http请求的流程耗时。
封装用的swig文件:

复制代码
1
2
3
4
5
6
7
8
%module bizBinary %{ #include "libbiz-binary.h" %} %include "libbiz-binary.h"

编译代码如下:

复制代码
1
2
3
4
5
6
7
// 编译so动态库 go build -buildmode=c-shared -o libbiz-binary.so main.go //编译python使用的模块 swig -python bizBinary.i gcc -c -fpic bizBinary_wrap.c -I/usr/local/include/python3.8 gcc -shared bizBinary_wrap.o -L. -lbiz-binary -o _bizBinary.so

最后会得到如下文件:

复制代码
1
2
3
4
5
6
7
8
. ├── biz-binary.go ├── libbiz-binary.h ├── libbiz-binary.so ├── bizBinary.i ├── bizBinary.py └── _bizBinary.so

必要文件为:

复制代码
1
2
3
4
5
. ├── libbiz-binary.so ├── bizBinary.py └── _bizBinary.so

测试之前需要设置c动态库的环境变量(不然报找不到 _bizBinary.so)

复制代码
1
2
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xxx/go/src/unitechs.com/biz-binary/t/

测试代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import time import requests import bizBinary def hello(): return "hello biz-binary" t=time.time() for i in range(1000000): bizBinary.hello2() print(time.time()-t) t2=time.time() for i in range(1000000): hello() print(time.time()-t2) bizBinary.hello() t = time.time() url="https://www.baidu.com" # url = "https://www.sogou.com/" for i in range(100): requests.get(url) print("python use time(s):", time.time() - t) t2 = time.time() for i in range(100): ret=bizBinary.HttpGet(url) print("go use time(s):", time.time() - t2)

hello测试,大概进入cgo栈比直接进python栈时间消耗为20倍。
python调用100次用时13秒左右,cgo调用100次用3秒左右。大致是因为request.get过程中进行了不少的数据解析和http协议解析,导致耗时太多。
另用原生go测试,时间也是3秒左右。和cgo调用差距不大。说明跨线程调用cgo的函数性能消耗是可以完全接受的。
cgo测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main import ( "fmt" "io/ioutil" "net/http" "time" ) func main() { t := time.Now() url := "https://www.baidu.com" for i := 0; i < 100; i++ { res, _ := http.Get(url) //var resByte []byte _, _ = ioutil.ReadAll(res.Body) //fmt.Println(i, "--", len(resByte)) } t2 := time.Now() tx := t2.Sub(t) fmt.Println("native go use time(s):", tx) }

另外用c直接调用cgo生成的HttpGet函数,性能略微快一点。
测试代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "libbiz-binary.h" #include <sys/time.h> void main(){ struct timeval start_time, end_time; double timeuse; gettimeofday(&start_time, NULL); // 开始时间 char* url="https://www.baidu.com"; for (int i=0;i<100;i++){ HttpGet(url); } gettimeofday(&end_time, NULL); // 结束时间 timeuse = (start_time.tv_sec - end_time.tv_sec) + (double)(start_time.tv_usec - end_time.tv_usec) / 1000000.0; printf("%lfn", timeuse); }

没给具体值是我懒,,主要是python太慢了让我失去了精确耗时进行比较的兴趣。

最后

以上就是细腻路人最近收集整理的关于cgo对go的性能影响cgo对go的性能影响的全部内容,更多相关cgo对go内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部