Cython wrapper 不够快,如何加快它的速度?

Cython wrapper not fast enough, how to speed it up?

我有一个 C++ 库,我想在 python 中包装它的一些功能。

该函数将给定的字符数组拆分为 5 个部分,不是实际拆分,而是我们传递给指针的结构,包含有关函数 returns 之后部分的信息。 5 个结构每个包含 2 个整数,一个表示部分的开始,另一个表示部分的长度。

python 包装器应该接受一个 python 字符串和 return 一个包含 5 个部分的字典或元组(也作为 python 字符串)。

我目前调用函数然后使用 python 切片语法根据子部分信息拆分 python 字符串的方法没有产生任何显着的速度提升。我意识到有很多类似的问题,但其中 none 个案例对我有所帮助。

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 字符串构造函数总是复制)。这不会留下很多开销需要删除。