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

标签 python performance cython

我有一个 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/

相关文章:

JavaScript 对象属性赋值

c# - 为什么对于这种特定情况,结构比类快得多?

python - 使用 Cython 优化 NumPy

Python 无法导入嵌套层次结构中生成的扩展

python - 如何省略 Sphinx 上的变量值?

python - 找不到 PySide 的 shiboken python 模块

python - AttributeError : dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found;使用 C 从 Python 运行 Go

python - kwargs 的多重继承

java - 对于少量信息,java 文件 i/o 或 derby 哪个更快?

python - 返回语句时速度慢