在 cython cdef 类 中使用特殊函数,例如 __add__

using special function such as __add__ in cython cdef classes

我想创建一个cython对象,可以进行加乘比较等方便的操作。但是当我编译这样的类时,它们似乎都有很多python开销。

一个简单的例子:

%%cython -a

cdef class Pair:
    cdef public:
        int a
        int b
        
    def __init__(self, int a, int b):
        self.a = a
        self.b = b
        
    def __add__(self, Pair other):
        return Pair(self.a + other.a, self.b + other.b)

p1 = Pair(1, 2)
p2 = Pair(3, 4)

p3 = p1+p2

print(p3.a, p3.b)

但我最终从带注释的编译器中得到了相当大的读数 似乎 __add__ 函数正在将对象从 python 浮点数转换为 cython 双精度数并进行大量类型检查。我做错了什么吗?

可能有几个问题:

  1. 我假设您使用的是 Cython 0.29.x(而不是较新的 Cython 3 alpha)。参见 https://cython.readthedocs.io/en/stable/src/userguide/special_methods.html#arithmetic-methods

    This means that you can’t rely on the first parameter of these methods being “self” or being the right type, and you should test the types of both operands before deciding what to do

    它可能将 self 视为未类型化,因此将 ab 作为 Python 属性访问。

    Cython 3 alpha 以不同方式处理特殊方法(参见 https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html#arithmetic-methods),因此您也可以考虑升级到它。

  2. 尽管对 __init__ 的调用有 C 类型的参数,但它仍然是一个 Python 调用,因此您无法避免对 Python 整数的参数进行装箱和拆箱.您可以避免此调用并执行以下操作:

    cdef Pair res = Pair.__new__()
    res.a = ... # direct assignment to attribute