Cython 中如何调用 c++ 的模板库?

2020-12-02 01:06:39 +08:00
 black11black

如题,最近有一个大量用到 python 中字典和列表寻址特性的科学计算函数,初步估算了一下循环次数在十亿级,纯 python 跑的非常慢,换到 pypy 以后加速快了三倍左右,但还是要等一分钟才能出结果。

于是想到能不能用 cython 加速,我以前 cython 都是了解皮毛,只跑过 helloworld 。 今天初步研究了一下感觉可行,按我的想法,因为要大量使用 python 列表,其加速方式大概就是要映射到 cpp 的 vector 了吧

在引入 stl 时遇到了无法引入的问题,有没有带佬指点一下哪错了

# 按我的理解安装 cython 时应该已经自带转换好的 stl 文件了吧
# 以下这段 C 库的引入是可以正常编译的
import cython
from libc.stdlib cimport atoi
from libc.string cimport memset

# 但是这里引入 CPP 的话却会报错
from libcpp.vector cimport vector

另外求问一下关于 python 字典的映射方式,在 cython 中应该怎么处理。比如现在有一个长度不确定的字典 name_dict,估测长度在一百万左右, 我需要大量使用诸如 name_dict['tom'] , name_dict['sam'] 这类字符串寻址来搜寻具体对象,对象内容不复杂,可以映射为结构体,但是这个字典该怎么搞?

谢谢大家

3039 次点击
所在节点    Python
25 条回复
ipwx
2020-12-02 17:36:36 +08:00
@qbqbqbqb #18L:用 int32_t, int64_t 这种
lovestudykid
2020-12-02 20:30:54 +08:00
@black11black 大概这样,CC=gcc-10 CXX=g++-10 python setup.py build_ext --inplace,也可以在 script 里设置环境变量。我用这个是因为 Mac 上默认调用 clang 有坑
black11black
2020-12-03 03:09:53 +08:00
@mckelvin
@wevsty
感谢大佬回复,我现在的需求很普通就是有一张从数据库导过来的二维表,这种表结构一般在 python 里是做成表套表,或者表套字典,像这样 [[],[],...] / [{},{},...] 。处理过程放到 cpp 的话确实转换开销蛮高的,所以我理解应该不能进行一些比较细粒度的 c 加速,最好是整个流程完全跑 c,这样只经过一次导入导出转换。

如果不用 vector 的话怎么处理这种结构呢?我感觉 vector 还是挺合适的,因为 push 添加很轻松,不用考虑内存问题。我现在遇到的问题是,我不会动态向 vector 里添加对象,比如我写在 for 循环中 cdef 一个对象然后 push 进 vector 里,这种语法是不允许的
black11black
2020-12-03 03:25:31 +08:00
试了一下,似乎在子 block 里新建对象并不需要 cdef 或者 new 之类的( new 在 cython 里似乎没有这个语法),直接 object()就能创建一个对象了。不过我定义结构体后看了一下 cython 生成的分析,似乎修改结构体当中的值仍然需要进行类型校正,似乎这部分是走的 python,并不能起到加速作用。

代码地址

https://paste.ubuntu.com/p/s4wk9QfqPB/

各位大佬指点一下最佳实践是什么,这么做开分析模式看的话感觉还是不太对
black11black
2020-12-03 03:27:42 +08:00
https://paste.ubuntu.com/p/cBgVXqWQJ8/

修正,上一楼代码有小错误

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/731186

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX