我有一个 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。
最佳答案
在 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 字符串构造函数总是复制)。这不会留下太多需要删除的开销。
关于python - Cython wrapper 不够快,如何加快它的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33501460/