简体   繁体   中英

Cython, pure Python mode: .pxd and @locals

I have a Python program that I want to speed up using Cython, while keeping the source readable by the Python interpreter ("Pure Python mode"). I get a 20% speed increase just by compiling it as it is. Then I created a .pxd file and tried to add some "@cython.locals(...)" throughout my .pyx script to fix the types of variables. But I see no difference in running time before and after the addition of these two features. So I have three similar questions:

First, I added in my .pyx :

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

Is this even doing anything?

Second, if I have in my .pyx a class

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

is there anything I can do to fix the type of "n" (as would a "cdef int n" after the "cdef class")?

Finally, if I have in my .pyx a function :

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

does it change anything to write the following in the .pxd? :

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

Thanks in advance for your help.

About your @cython.locals , I think you should try placing it just before the __init__ method, not before the class declaration, because it refers to the constructor.

Consider using @cython.cclass for declaring a cdef class.

To fix the type of a variable, use cython.declare() , or @cython.locals , see magic attributes .

The options above must be included in the .py or .pyx file, and are special cython functions and/or decorators.

The alternative is to keep your code in a .py file as pure python, and use an augmenting .pxd file with the same name. The python code will look cleaner, but it may take longer to maintain the separate .pxd file. See this section. This is basically what you're doing in your last example.

In the end I got help from Cython's official forum at Google Groups. If one writes a .pyx file, the .pxd is only to share function definitions with other modules; in particular, it will not enhance the original functions and all three examples above add nothing from compiling the raw python script.

One can use a .pxd in conjunction with a raw .py though, to fix variable types of simple functions and class attributes, but it has many limitations.

@cython.locals does not allow to touch class attributes, but only (non- xxx ) function arguments. It would do nothing in this particular case. In general I think these decorators are not the correct approach.

The best way to do is probably to rewrite some of the functions with the Cython syntax in a .pyx, in public mode ("cpdef" creates a Python wrapper), compile it, and then import the function/classes into the Python code as one does with other libraries. But it is not really pure Python anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM