cython编译 - import vs cimport

时间:2015-03-27 22:26:43

标签: python-3.x cython

Cython的新手(也许这是一个基本问题)。考虑两个来自this blog here

的例子
# code 1
import numpy as np

def num_update(u):
    u[1:-1,1:-1] = ((u[2:,1:-1]+u[:-2,1:-1])*dy2 + 
                    (u[1:-1,2:] + u[1:-1,:-2])*dx2) / (2*(dx2+dy2))

# code 2
cimport numpy as np

def cy_update(np.ndarray[double, ndim=2] u, double dx2, double dy2):
    cdef unsigned int i, j
    for i in xrange(1,u.shape[0]-1):
        for j in xrange(1, u.shape[1]-1):
            u[i,j] = ((u[i+1, j] + u[i-1, j]) * dy2 +
                      (u[i, j+1] + u[i, j-1]) * dx2) / (2*(dx2+dy2))

假设我使用以下setup.py脚本编译第一个文件:

# setup file for code 1
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext = Extension("laplace", ["laplace.pyx"],)
setup(ext_modules=[ext], cmdclass = {'build_ext': build_ext})

以及带有以下setup.py脚本的第二个文件:

# setup file for code 2
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

import numpy

ext = Extension("laplace", ["laplace.pyx"],
    include_dirs = [numpy.get_include()])

setup(ext_modules=[ext], cmdclass = {'build_ext': build_ext})

在第一种情况下,我使用常规numpy并且未在设置文件中导入numpy,而在第二种情况下,我使用numpy导入cimport,使用cdef声明变量,但在设置文件中也包含numpy

无论如何

Cython编译第一个代码(第一个代码似乎有用)。

在使用Cython(通过安装文件)编译之前使用cimportcdef而不是在使用Cython编译之前使用cimportcdef会有什么好处(通过安装文件)?

2 个答案:

答案 0 :(得分:12)

Cython中的

import numpy与Python相同,但cimport numpy告诉Cython加载声明文件:

https://github.com/cython/cython/blob/master/Cython/Includes/numpy/init.pxd

其中声明了所有C-API函数,常量和类型,还包括头文件,例如numpy/arrayobject.h

如果使用np.ndarray[...]声明变量,Cython将知道如何将数组元素访问转换为c代码,这比Python的[]运算符快得多。

您需要告诉c编译器setup.py中的numpy头文件在哪里,因此您可以调用numpy.get_include()来获取路径。

答案 1 :(得分:1)

Cython可以编译普通的python代码,所以你的第一个编译。

一般来说,你为cython标记的类型越多,你获得更好性能的可能性就越大。因此,如果您想以灵活性换取速度,那么您的决定就是。

运行cython -a your_test.pyx以查看cython如何编译代码的注释版本。黄色表示您的代码转换为大量C代码(大致意味着性能损失),而白色意味着它只转换为几行C。

如果你没有花时间在这里问,而是通过官方网站上的guide阅读,你可能已经有了更好的理解。