• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

cgo对go的性能影响

武飞扬头像
Chise1
帮助1

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.百度.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.百度.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.百度.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("%lf\n", timeuse);
}
学新通

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfafje
系列文章
更多 icon
同类精品
更多 icon
继续加载