【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    在上一篇文章中,我们成功的通过Python调用Go代码,并且把计算密集的交给了Go来进行计算,虽然计算的很快,但是在获取返回值时,似乎有点让人诧异,并不是我们想象的那样子。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

/2 造成返回值错误的原因是什么?/

        在上一篇文章中,我们似乎都忘了一张图。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    .go文件是Go的,不多说,.so是Python调用Go的文件,那.h文件是什么???似乎很没有存在感,我们的问题出,也就出在这个.h文件中,我们打开看一下

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    我们往下翻翻,会找到extern开头的声明,这个意思是将Go代码转为C代码一一对应的参数,可见,转为C的是GoInt类型,这个类型具体什么意思呢???再找找看。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    在上面其实大概可以发现,GoInt其实就是GoInt64,GoInt64的类型是long long类型,这是玩意???

    其实我们在Python中调用.so文件使用的是ctypes模块,这个是有一个对应表的。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

/3 Python,ctypes , c 类型对应表/

官网地址:

https://docs.python.org/3.5/library/ctypes.html

登录后复制

ctypes typeC typePython typec_bool_Boolbool (1)c_charchar1-character  bytes objectc_wcharwchar_t1-character  stringc_bytecharintc_ubyteunsigned charintc_shortshortintc_ushortunsigned shortintc_intintintc_uintunsigned intintc_longlongintc_ulongunsigned longintc_longlong__int64 or long longintc_ulonglongunsigned  __int64 or unsigned long longintc_size_tsize_tintc_ssize_tssize_t or Py_ssize_tintc_floatfloatfloatc_doubledoublefloatc_longdoublelong doublefloatc_char_pchar * (NUL  terminated)bytes object  or Nonec_wchar_pwchar_t * (NUL  terminated)string or Nonec_void_pvoid *int or None

    根据上述表格我们可以发现,在C中的long long类型对应的ctype类型是c_longlong。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    所以我们需要在Python将.so中的返回值改一下,不能使用系统默认的了。代码如下:

from ctypes import *import timeclass StructPointer(Structure):    # 根据查表,C中的long long,对应的ctypes 是 c_longlong    # _fields_必须是[](列表)类型,里面写对应的类型,固定格式    _fields_ = [("p", c_longlong,),]if __name__ == '__main__':    beginTime = time.time()    s = CDLL("s1.so")  # 加载s1.so文件    s.run.restype = StructPointer # 声明.so的run函数返回值类型,固定格式    result = s.run(100000000)  # 调用Go生成的.so文件里面的run函数    print("result:", result.p)# 此处需要调用.p来获取值,和 _fields_对应    endTime = time.time()    print("耗时:", endTime - beginTime)

登录后复制

    再次执行:

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    

    可以看到,这次Python执行的结果和Go执行结果就一个样了。继续,换个数字试试看。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    基本可以确定,这次是没问题了。

/4 如果返回的是字符串呢?/

Go代码

package mainimport (  "C" //C必须导入  "fmt")//export runfunc run(n int) int{  /*    必须要export 函数名    //是注释的意思,相当于Python中的 #    我也是第一次见注释还有作用  */  sum := 0  for i := 0; i 

登录后复制

    下面一起来理解.h文件。编译之后打开.h文件如下图所示:

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    可以看到,在extern的函数成了两个,但是他的返回值是GoString,继续找。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    可以发现,其实GoString就是_GoString_,继续找。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    

    这次是一个结构体,里面其实是两个值,不在是单独的long long了,那Python中的继承类也要改一下了。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

下面基本同上。

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

完整代码如下:

from ctypes import *import timeclass StructPointer(Structure):    # 根据查表,C中的long long,对应的ctypes 是 c_longlong    # _fields_必须是[](列表)类型,里面写对应的类型,固定格式    _fields_ = [("p", c_longlong,),]class StrPointer(Structure):    # typedef struct { const char *p; ptrdiff_t n; } _GoString_;    # ptrdiff_t == long long    _fields_ = [("p", c_char_p), ("n", c_longlong)]if __name__ == '__main__':    beginTime = time.time()    s = CDLL("s1.so")  # 加载s1.so文件    s.run.restype = StructPointer # 声明.so的run函数返回值类型,固定格式    result = s.run(100000798)  # 调用Go生成的.so文件里面的run函数    print("result:", result.p)# 此处需要调用.p来获取值,和 _fields_对应    s.speak.restype = StrPointer    speakStr = s.speak()    # 返回的是字节类型,需要转字符串,返回的内容在.p中,.n是切的长度,后面会跟一些介绍,不需要    speakStr = str(speakStr.p[:speakStr.n], encoding="utf-8")    print("speak:",speakStr)    endTime = time.time()    print("耗时:", endTime - beginTime)

登录后复制

结果:

【进阶篇】Python+Go——带大家一起另寻途径提高计算性能

    可以看到,调用Go代码成功的拿到了正确的字符串返回值,如果没有 .restype = StrPointer拿到的会是什么呢?拿到会和原来的一样,一堆数字,这里就不举栗子了。

/5 小结/

    至此,基本上在Python调用Go代码上的大坑都解决了,最复杂的是返回字符串类型,查了很多相关资料才解决。

    关于返回其他类型的Python的class怎么写,我相信已经难为不到你们了,最复杂的都解决了,最简单的还不会吗?(除字符串类型以外其他_fields_都是一个字段的)

    我相信各位小伙伴学习能力还是很强的,人生苦短,Python当歌,加油,奥利给!

以上就是【进阶篇】Python+Go——带大家一起另寻途径提高计算性能的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2487500.html

(0)
上一篇 2025年3月4日 22:32:08
下一篇 2025年3月4日 22:32:34

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论