我有一个C ++库,我想在python中包含它的一些功能。
该函数将给定的字符数组拆分为5个部分,而不是实际的拆分,但是我们传递指针的结构,包含函数返回后的部分信息。 5个结构每个包含2个整数,一个表示零件的开头,另一个表示零件的长度。
python包装器应该接受一个python字符串并返回5个部分的字典或元组(也作为python字符串)。
我当前调用函数然后使用python切片语法基于子部分信息拆分python字符串的方法并没有产生任何显着的速度增益。我意识到有很多类似的问题,但这些案例都没有对我有所帮助。
Cython定义代码是 -
cdef extern from "parse.h" namespace util
ctypedef struct part:
int begin;
int len;
ctypedef struct Parsed:
part part1;
part part2;
part part3;
part part4;
part part5;
void ParseFunc(const char* url, int url_len, Parsed* parsed)
Cython代码是 -
cimport parseDef
def parse(url, url_len):
cdef parseDef.Parsed parsed
parseDef.parseFunc(url, url_len, &parsed)
part1 = url[parsed.part1.begin:parsed.part1.begin+parsed.part1.len]
#similar code for other parts
return (part1, part2, part3, part4, part5)
此包装器的典型字符串大小通常为10-50。
答案 0 :(得分:1)
通过const char*
而不是字符串
cimport parseDef
def parse(url, url_len):
cdef const char* url_as_char_ptr = url # automatic conversion
cdef parseDef.Parsed parsed
parseDef.parseFunc(url, url_len, &parsed)
part1 = url_as_char_ptr[parsed.part1.begin:parsed.part1.begin+parsed.part1.len]
#similar code for other parts
return (part1, part2, part3, part4, part5)
我认为你不能打败这个,主要是因为生成的c代码实际上非常有效。索引行转换为类似
的内容__pyx_t_2 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_url_as_char_ptr + idx1, idx2 - idx1)
(注意我已将parsed.part1.begin
替换为idx1
只是为了便于阅读,因为我使用稍微不同的代码对此进行测试,因为我没有parseFunc
。您可以使用cython -a yourfile.pyx
检查确切的代码并查看html输出。
这基本上只是调用Python c-api字符串构造函数。这必然会传递它传递的字符串的副本,但你无法避免(Python字符串构造函数总是复制)。这不会留下很多开销。