1 basic_euclidean.pyx
1.1 cimport 部分
python
from libc.math cimport sqrt
from libc.math cimport fmin
#使用 cimport 从 C 的标准库 libc 中导入数学函数 sqrt(平方根)和 fmin(两个浮点数的最小值)
python
cimport numpy as np
'''
导入 NumPy 的 Cython 接口
允许 Cython 代码以高效的方式直接访问 NumPy 数组的底层 C 数据结构。
这对于提高数组操作的性能非常重要。
'''
import numpy as np
'''
导入标准的 Python NumPy 模块。
这允许在 Cython 代码中使用所有标准的 NumPy 函数和功能,就像在普通的 Python 代码中一样
'''
from cpython cimport bool
'''
使用 cimport 从 Cython 的 cpython 模块中导入 C 的布尔类型
允许 Cython 代码使用 C 语言的布尔类型,而不是 Python 的布尔类型。
C 语言的布尔类型在某些情况下比 Python 的布尔类型更高效,尤其是在需要与其他 C 语言代码或库交互时。
'''
1.1.1 之后出现np的时候,应该是Cython接口还是Python Numpy 模块呢?
- 在实际编码过程中,Cython 会根据上下文判断
np
的具体指代。- 如果你在代码中同时使用了两种导入方式,通常 Cython 会优先使用 Cython 接口的 NumPy,因为它提供了对底层 C 数据的直接访问,从而可以优化性能。
- 但是,如果使用了 NumPy 的某些高级特性或函数,这些是只在 Python 层面提供的,Cython 将使用标准的 Python NumPy 模块。
- 因此,当代码中有两个不同类型的
np
导入时,Cython 会根据具体的使用情况智能地选择适当的版本。
1.2 eucl_dist 计算两个点之间的欧氏距离
还有一个用def定义的python版本的函数(内容一样)
1.2.1 为什么要创建一个python版本的函数,一个Cython版本的函数?
创建两个版本的函数,一个使用 cdef
定义( _eucl_dist
),另一个使用 def
定义( c_eucl_dist
),通常是出于以下几个原因:
-
性能与可访问性:
cdef
定义的函数(_eucl_dist
)是为了性能优化。这些函数在 Cython 模块内部以 C 的速度运行,但它们不能直接从 Python 代码中调用。这意味着,如果你有一些性能关键的内部计算,使用cdef
函数是理想的选择。def
定义的函数(c_eucl_dist
)可以从 Python 代码调用。这种函数对于提供库的外部接口很有用,使得其他不使用 Cython 的 Python 代码也能访问这些功能。
-
代码重用与维护:
-
通过将核心功能编写在
cdef
函数中,并在def
函数中调用它(这里是选择了写一遍一模一样的代码),可以在保持性能的同时减少代码重复。这样,无论是从 Cython 还是从 Python 级别调用,都使用相同的底层实现。 -
这种做法还有助于维护,因为任何逻辑更改只需在一个地方进行,即
cdef
函数。
-
1.3 c_point_to_seg 计算点到线段的距离
1 sspd.pyx
1.1 import 与 cimport
python
from libc.math cimport fmin
from .basic_euclidean import c_point_to_trajectory
from .basic_geographical import c_point_to_path
cimport numpy as np
from numpy.math cimport INFINITY
1.1.1 cimport
-
cimport 是 Cython 特有的语句,主要用于导入 C 语言扩展或其他 Cython 模块中定义的类型、函数和变量
-
要直接访问 C 语言层面的功能时,需要使用 cimport
-
利用 Cython 的能力来直接与 C 语言层面的代码或数据结构交互,从而提高了代码的运行效率
-
cimport numpy as np :
- 使用 cimport 来导入 NumPy 的 Cython 接口
- numpy 在这里不是标准的 Python NumPy 模块,而是一个特殊的 Cython 定义的接口,允许直接访问 NumPy 数组的底层 C 结构
- 使用这种方式导入 NumPy 数组可以显著提高性能,因为它允许 Cython 代码以更接近 C 语言的方式操作这些数组,绕过了 Python 层面的开销
-
from numpy.math cimport INFINITY
- 从
numpy.math
模块中导入INFINITY
常量 - 同样,这里的
numpy.math
不是标准 Python 模块,而是 NumPy 的 Cython/C 接口
- 从
1.1.2 import
至于为什么前两个是import,我们看一下对应文件声明的部分
def
vs.cdef
:def
:在 Cython 中使用def
定义的函数是 Python 函数。这意味着它们可以像任何普通 Python 函数那样被 Python 代码调用。这些函数遵循 Python 的函数调用约定,可以接受 Python 对象作为参数,并返回 Python 对象。cdef
:相比之下,cdef
用于定义 Cython 函数或变量,这些函数或变量只能在 Cython 模块内部使用,不能直接从 Python 代码中调用。cdef
函数遵循 C 语言的调用约定,通常用于提高性能。
- 由于
c_point_to_trajectory
函数是用def
而不是cdef
定义的,它可以从 Python 代码中调用。- 因此,即使它是在一个 Cython 模块中定义的,这个模块仍然需要使用标准的 Python
import
语句来导入,因为它提供了 Python 接口
- 因此,即使它是在一个 Cython 模块中定义的,这个模块仍然需要使用标准的 Python
- 但是,尽管
c_point_to_trajectory
是一个 Python 函数,它依然利用了 Cython 的特性来提高性能