【问题标题】:Optimize away PyFloat_FromDouble, Pyx_GetItemInt and PyObject_RichCompare in Cython generated C code在 Cython 生成的 C 代码中优化掉 PyFloat_FromDouble、Pyx_GetItemInt 和 PyObject_RichCompare
【发布时间】:2018-09-17 20:26:22
【问题描述】:

我正在尝试在 Cython 中为 Python 编写一个运行长度编码算术库。下面你会看到声明和算法热循环的重要部分的外观。它有两个地方,Python 交互较多和中等,第 73-74 行和第 77 行。为重度 Python 交互部分生成的 C 代码显示在最后的图片中。我只会在这里询问如何解决 73-74,因为我认为 77 的修复将是类似的。

如您所见,1) 生成的 C 代码中有很多类型转换,2) 它使用 Richcompare 和 3) getitemint。我不明白为什么:1)类型应该相同,2)比较应该可以在 C 级别进行,因为它们只是比较相同类型的数字,3)getitem 应该是多余的,因为你只是在查找一个C 数组中的索引。

如何解决这个问题以优化我的代码?问题是 numpy 数组声明创建 Python 对象并且我需要以某种方式给它们一个指针吗?

在这里你可以看到 Cython 为我的热循环中的两个深黄色和浅黄色的地方生成的 C 代码:

【问题讨论】:

    标签: python numpy types cython


    【解决方案1】:

    您尚未输入 nvsnrs,因此它们被视为 Python 对象(因此必须将 nv 转换为 Python 对象以进行比较)。

    做:

    cdef long[:] nrs = np.zeros( # ... as before
    cdef double[:] nvs = np.zeros( # ... as before
    

    (此外,虽然 html 的图像很有帮助,但如果您也将代码作为文本包含在内,它会更容易阅读......)

    【讨论】:

    • 是的,我刚才在想这个;图像也不是 google/hooliable。
    • 我确实得到了突出显示的价值。但对我来说,主要是它们不可复制——我无法在编辑器中快速获取代码并进行更改。
    • @TheUnfunCat 我建议使用long[::1] nrs=...,也用于函数的签名。这清楚地表明内存是连续的,从而导致生成更有效的代码,例如参见stackoverflow.com/q/49058949/5769463
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 2017-04-08
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多