前言:
今天大家对“动态加载c语言”大概比较重视,兄弟们都想要剖析一些“动态加载c语言”的相关知识。那么小编也在网摘上网罗了一些有关“动态加载c语言””的相关文章,希望大家能喜欢,小伙伴们一起来了解一下吧!很多人都说Python慢,Python在计算密集型场景确实慢,一般建议由其他语言实现。
那么什么场景下是计算密集型?下面举一个简单的例子来看看。
本文不做严格的性能比对,用我个人的MacBook pro来测试。
下图是某一个场景下Python和Go不严格的性能测试结果,看每秒处理速度提升接近200倍,平均处理时间从22ms提升到不足0.15ms,相信在一般的业务中0.15ms的引入时延基本上不会影响到正常业务的进行了。
Python计算22ms左右
img是一个灰度图的矩阵,每个像素是0~255的1个值,这个值映射到tmp_map中有一个对应的值。
下面的函数就是求这个图像最大的10个点映射值的平均值
def handle_temp(self, img: np.ndarray, img_w, img_h, tmp_map: array.array): max_temp_list = [0 for i in range(10)] for i in range(0, img_w): for j in range(0, img_h): v = img[i*img_h+j] tmp = tmp_map[v] for i in range(10): if max_temp_list[i] >= tmp: break if i > 0: max_temp_list[i-1] = max_temp_list[i] max_temp_list[i] = tmp return sum(max_temp_list)/10
我们做循环处理反复计算这个结果,10秒钟统计一次,统计结果展示如下,看到每次计算了大约11万的点,python平均22ms左右的时间。
handle 440, cost:10.008, avg:43.96 个/秒, avg cost:22.746ms, point:110592handle 427, cost:10.014, avg:42.64 个/秒, avg cost:23.452ms, point:110592handle 451, cost:10.005, avg:45.08 个/秒, avg cost:22.185ms, point:110592handle 425, cost:10.006, avg:42.47 个/秒, avg cost:23.544ms, point:110592handle 465, cost:10.017, avg:46.42 个/秒, avg cost:21.542ms, point:110592handle 459, cost:10.013, avg:45.84 个/秒, avg cost:21.815ms, point:110592handle 423, cost:10.018, avg:42.23 个/秒, avg cost:23.682ms, point:110592handle 448, cost:10.004, avg:44.78 个/秒, avg cost:22.330ms, point:110592handle 441, cost:10.017, avg:44.02 个/秒, avg cost:22.715ms, point:110592handle 443, cost:10.016, avg:44.23 个/秒, avg cost:22.609ms, point:110592
Python调用go性能提升近200倍
使用go来重写计算部分,逻辑差不多,实现也比较简单
//遍历横坐标for iX := x; iX < x+w; iX++ { for iY := y; iY < y+h; iY++ { cur := iX*imgH + iY //fmt.Println(iX, iY, cur) //获取像素值 rgb := imgArray[cur] // 范围保护 if rgb < 0 || rgb > 255 { continue } for idx := 0; idx < 10; idx++ { // 从小到大比较之前的温度值 if maxTempArray[idx] < tmpArray[rgb] { if idx > 0 { // 当前位置的往前移动 maxTempArray[idx-1] = maxTempArray[idx] } //最新上top10的温度替换, 如果是索引0的,直接替换上榜 maxTempArray[idx] = tmpArray[rgb] } else { //跳出 break } } }}//计算总数sumTemp := 0for idx := 0; idx < 10; idx++ { sumTemp += maxTempArray[idx]}
同样的进行性能测试,每次计算不到0.2ms,相对于直接使用Python计算,性能上有接近200倍的提升。
handle 76718, cost:10.000, avg:7671.70 个/秒, avg cost:0.130ms, point:110592handle 77479, cost:10.000, avg:7747.85 个/秒, avg cost:0.129ms, point:110592handle 76495, cost:10.000, avg:7649.50 个/秒, avg cost:0.131ms, point:110592handle 76349, cost:10.000, avg:7634.83 个/秒, avg cost:0.131ms, point:110592handle 76104, cost:10.000, avg:7610.30 个/秒, avg cost:0.131ms, point:110592handle 76266, cost:10.000, avg:7626.53 个/秒, avg cost:0.131ms, point:110592handle 74852, cost:10.000, avg:7485.14 个/秒, avg cost:0.134ms, point:110592handle 75608, cost:10.000, avg:7560.78 个/秒, avg cost:0.132ms, point:110592handle 74283, cost:10.000, avg:7428.22 个/秒, avg cost:0.135ms, point:110592handle 73874, cost:10.000, avg:7387.31 个/秒, avg cost:0.135ms, point:110592handle 74223, cost:10.000, avg:7422.21 个/秒, avg cost:0.135ms, point:110592handle 69534, cost:10.000, avg:6953.33 个/秒, avg cost:0.144ms, point:110592
Python调用go的实现
得益于go的强大,Python调用go跟调用C的dll一样,有朋友问为啥不直接用C来实现dll,主要是go编译发布方便,代码写起来也稍微简单些。
下面是Python调用范例
# dll加载img_handle = CDLL(dll_path)# getMaxTemp(img *uint8, imgW int, imgH int, x int, y int, w int, h int, tempIdx *int16) intimg_handle.argtypes = [POINTER(c_uint8), c_int, c_int, c_int, c_int, c_int, c_int, POINTER(c_int16)]# 返回类型声明img_handle.restype = c_int# 计算max_temp = img_handle.getMaxTemp(ndarray.ctypes.data_as(POINTER(c_uint8)), img_w, img_h, 0, 0, img_w, img_h, ((POINTER(c_uint32) * 256).from_buffer(tempIdx)))# getMaxTemp放到了1000倍,还原;再除以10还原到原始温度值return max_temp/1000/10
go函数的声明方式,特别注意有几个点
①需要import "C"
②函数名前面需要备注export 函数名,特殊的语法糖
③编译的时候需要注意buildmode属性设置,如下
go build -o detect_img -buildmode=c-shared detect_img.go
package mainimport ( "C" "fmt" "unsafe")// 支持最大的宽度和高度const ( MAX_IMG_WIDTH = 8000 MAX_IMG_HEIGHT = 6000 TEMP_IDX_SIZE = 256)//export getMaxTempfunc getMaxTemp(img *uint8, imgW int, imgH int, x int, y int, w int, h int, tempIdx *uint32) int {
标签: #动态加载c语言