让 for 和 while 循环具有 C 级别的性能

简介: 让 for 和 while 循环具有 C 级别的性能

Python 的 for 和 while 循环是灵活并且高级的,语法自然、读起来像伪代码。而 Cython 也支持 for 和 while,无需修改。但由于循环通常占据程序运行时的大部分时间,因此我们可以通过一些优化,确保 Cython 能够将 Python 循环转换为高效的 C 循环。

n = 100
for i in range(n):
    ...

上面是一个标准的 Python for 循环,如果这个 i 和 n 是静态类型,那么 Cython 就能生成更快的 C 代码。

cdef Py_ssize_t i, n = 100
for i in range(n):
    ...
# 这段代码和下面的C代码是等效的
"""
for (i=0; i<n; ++i) {
  /* ... */
}
"""

所以当通过 range 进行循环时,我们应该将 range 里面的参数以及循环变量换成 C 的整型。如果不显式地进行静态声明的话,Cython 就会采用最保守的策略:

cdef Py_ssize_t n = 100
for i in range(n):
    print(i + 2 ** 100)

在循环的时候,如果我们使用了变量 i,那么在和一个数字相加的时候,由于 Cython 无法确定是否会发生溢出,因此会保守的选择 Python 的整型。

如果我们能保证表达式中一定不会发生溢出,那么可以显式地将 i 也声明为 C 的整数类型。

当然不光是整型,其它的 Python 类型也可以提前声明,举个例子:

cdef list lst = [
    {"name": "satori", "age": 17},
    {"name": "koishi", "age": 16},
    {"name": "marisa", "age": 15},
]
# lst 里面都是字典,在遍历之前可以提前声明好
cdef dict item
for item in lst:
    print(f"{item['name']}, {item['age']}")
"""
satori, 17
koishi, 16
marisa, 15
"""
# 通过 cdef dict item 提前声明循环变量的类型
# 然后遍历以及操作的时候,速度会快很多
# 因为我们实现了基于类型的优化

以上是 for 循环,至于 while 循环也是同理,说白了还是规定好类型,实现基于类型的优化。

当然目前的优化还只是一部分,我们将在后续系列中了解优化循环体的更多信息,包括 Numpy 在 Cython 中的使用以及类型化内存视图。

循环的另一种方式

对于 Cython 而言,循环还有另一种方式,不过已经过时了,不建议使用,了解一下即可:

cdef int i
# 等价于 for i in range(0, 5)
# 不可以写成 for i from i >=0 and i < 5
for i from 0<= i < 5:  
    print(i)
"""
0
1
2
3
4
"""
# for i in range(0, 5, 2)
for i from 0 <= i < 5 by 2:  
    print(i)
"""
0
2
4
"""

这种循环在语法上看起来很酷,但是已经过时了,因此直接使用 range 即可。

相关文章
|
安全 Go 开发者
使用 contextvars 管理上下文变量
使用 contextvars 管理上下文变量
304 0
|
存储 Unix Python
shutil:更优雅地拷贝文件
shutil:更优雅地拷贝文件
410 0
|
存储 编译器 Linux
Cython 和 Python 的区别
Cython 和 Python 的区别
446 0
|
编译器 API C语言
Cython 是什么?为什么会有 Cython?
Cython 是什么?为什么会有 Cython?
436 0
|
编译器 Linux C语言
编译并运行 Cython 代码的几种方式
编译并运行 Cython 代码的几种方式
588 2
|
存储 索引 Python
深度解密 Python 列表的实现原理
深度解密 Python 列表的实现原理
247 14
|
网络协议 算法 Linux
深度解密 TCP 三次握手与四次挥手
深度解密 TCP 三次握手与四次挥手
386 9
|
存储 Go C语言
Python 的整数是怎么实现的?这篇文章告诉你答案
Python 的整数是怎么实现的?这篇文章告诉你答案
283 7
|
存储 自然语言处理 编译器
深度解密 Python 的字节码
深度解密 Python 的字节码
561 8
|
Python
《Cython 从入门到精通》PDF 版本新鲜出炉啦!!!
《Cython 从入门到精通》PDF 版本新鲜出炉啦!!!
342 1