概述
cgo对go的性能影响
概述
做go封装给python和perl进行使用的时候,使用cgo->swig->python、perl流程,对整个流程的性能进行了粗略的性能比较。(在deepin环境进行的测试)
cgo代码
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文件:
%module bizBinary
%{
#include "libbiz-binary.h"
%}
%include "libbiz-binary.h"
编译代码如下:
// 编译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
最后会得到如下文件:
.
├── biz-binary.go
├── libbiz-binary.h
├── libbiz-binary.so
├── bizBinary.i
├── bizBinary.py
└── _bizBinary.so
必要文件为:
.
├── libbiz-binary.so
├── bizBinary.py
└── _bizBinary.so
测试之前需要设置c动态库的环境变量(不然报找不到 _bizBinary.so)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xxx/go/src/unitechs.com/biz-binary/t/
测试代码:
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测试代码
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函数,性能略微快一点。
测试代码如下:
#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的性能影响cgo对go的性能影响所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复