Cython,纯Python模式:.pxd和@locals

时间:2014-05-21 13:24:50

标签: python cython

我有一个Python程序,我想加速使用Cython,同时保持Python解释器的源可读("纯Python模式")。我只是通过编译它来获得20%的速度提升。然后我创建了一个.pxd文件并试图添加一些" @ cython.locals(...)"在我的.pyx脚本中修复变量类型。但我发现在添加这两个功能之前和之后的运行时间没有区别。 所以我有三个类似的问题:

首先,我在.pyx中添加:

@cython.locals(start=cython.int, end=cython.int)
class C(object):
    def __init__(self, start, end)
        self.start = start
        self.end = end

这甚至做了什么吗?

其次,如果我在.pyx中有一个班级

class Counter(object):
    def __init__(self):
        self.n = 0
    def __call__(self, x):
        self.n += 1

我能做些什么来修复" n" (就像" cdef int n"" cdef class")?

最后,如果我在.pyx中有一个函数:

def count():
    <do something with variables a,b,c>

是否会更改任何内容以在.pxd中编写以下内容? :

cpdef inline count():
    cdef:
        int a
        int b
        int c

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

关于你的@cython.locals,我认为你应该尝试将它放在__init__方法之前,而不是在类声明之前,因为它引用了构造函数。

考虑使用@cython.cclass声明cdef类。

要修复变量类型,请使用cython.declare()@cython.locals,请参阅magic attributes

上面的选项必须包含在.py.pyx文件中,并且是特殊的cython函数和/或装饰器。

另一种方法是将代码保存在.py文件中作为纯python,并使用具有相同名称的扩充.pxd文件。 python代码看起来更干净,但维护单独的.pxd文件可能需要更长时间。请参阅this部分。这基本上就是你在上一个例子中所做的。

答案 1 :(得分:0)

最后,我得到了来自Google Groups的Cython官方论坛的帮助。如果写一个.pyx文件,.pxd只是与其他模块共享函数定义;特别是,它不会增强原始函数,上面的所有三个例子都没有添加编译原始python脚本。

可以将.pxd与raw .py一起使用来修复变量类型的简单函数和类属性,但它有很多限制。

@ cython.locals不允许触及类属性,只允许(非 xxx )函数参数。在这种特殊情况下,它什么都不做。总的来说,我认为这些装饰器不是正确的方法。

最好的方法是使用.pyx中的Cython语法,在公共模式下重写一些函数(&#34; cpdef&#34;创建一个Python包装器),编译它,然后导入函数/类与Python代码一样,与其他库一样。但它不再是纯粹的Python了。