cpython/pypy/cython初体验
2025-07-17
测试程序
main.py
import time
def calculate(n):
total = 0
for i in range(n):
total += i**2
return total
if __name__ == '__main__':
t = time.time()
result = calculate(10000000)
print("%s" % result)
print(time.time() - t)
默认python运行
# python -V
Python 3.6.8
# python main.py
333333283333335000000
3.708322763442993
CPython
cpython实际就是python的默认C语言实现,类似的还有jpython(java实现),IronPython(.net实现)
理论运行和直接用默认python运行一致,但是如果自己拿源码编译,可能因为编译选项等差异,会导致运行效率有区别
此处不再演示
pypy
// 安装
# wget https://downloads.python.org/pypy/pypy3.10-v7.3.12-linux64.tar.bz2
# tar xvf pypy3*.tar.bz2
// 运行
# cd pypy3*/bin
# ./pypy -V
Python 3.10.12 (af44d0b8114cb82c40a07bb9ee9c1ca8a1b3688c, Jun 15 2023, 12:39:27)
[PyPy 7.3.12 with GCC 10.2.1 20210130 (Red Hat 10.2.1-11)]
// 测试
# ./pypy main.py
333333283333335000000
0.25452280044555664
cython
cython本质是python+c语言的混编,因此代码需要做修改,对于已知类型使用cdef显示定义类型,可以减少python运行时识别类型的过程
因此可以显著提升性能,当然除了定义类型还有其他手段提升性能
main.pyx
// 代码修改
import time
def calculate(n):
"""使用Python对象处理大整数"""
cdef Py_ssize_t i
total = 0 # 保留Python的任意精度整数
for i in range(n):
total += i * i
return total
def main():
cdef double t
cdef object result
cdef int n = 10000000
t = time.time()
result = calculate(n)
print(result)
print(time.time() - t)
setup.py
# cat setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize(
"main.pyx",
compiler_directives={
'language_level': "3",
'boundscheck': False,
'wraparound': False
}
)
)
// 安装
# pip3 install cython
// 编译
# python setup.py build_ext --inplace
// 生成出main.cpython-36m-x86_64-linux-gnu.so
# ll
total 536K
drwxr-xr-x 4 root root 63 Jul 16 12:56 build
-rw-r--r-- 1 root root 261K Jul 17 07:15 main.c
-rwxr-xr-x 1 root root 261K Jul 17 07:15 main.cpython-36m-x86_64-linux-gnu.so
-rw-r--r-- 1 root root 387 Jul 17 07:15 main.pyx
-rw-r--r-- 1 root root 268 Jul 16 12:38 setup.py
// 运行
# python -c "import main;main.main()"
333333283333335000000
0.5726358890533447