python代码加速运行的四种方法详解

 更新时间:2025年06月20日 09:49:16   作者:钟烁卓  
这篇文章主要为大家详细介绍了python中代码加速运行的四种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

1.python执行原理

python执行过程:python脚本语言(.py)或者cython语言(.pyx)–解释器解释–>字节码(.pyc)–虚拟机执行–>机器码(看不到,可以在cpu上跑起来)。

由于没有原生的编译时类型检查,所有的类型的检查都被移交给了运行时,执行一行Python代码很可能需要做不只一行的类型检查、边界检查,因此python比起C++等会慢很多。

python的解释器可以多种,常见的是cpython(最常用)、Ipython(基于cpython的交互式解释器)、pypy(动图编译python代码,运行速度快,与cpython有少数不同)、Jython、IronPython。

2.Cypthon(推荐,速度与numba接近)

Cython是一门语言,文件名以.pyx结尾。其是python的超集,即兼容python,Cython与python类似于C++与C的关系。同时Cython也是一个编译器的名称,其可将Cython语言写的pyx文件(包含.py文件)直接编译成动态库,从而获得近乎于写CXX语言的性能。

官网推荐使用setuptools (setup.py)的方法来编译.pyx/.py代码。如以下文件树,

├── os
│   └── ros_os.py
│   └── setup.py

目标是将os文件夹下的ros_os.py编译成.so动态库,因此在ros_os.py同级目录下新建一个setup.py文件。setup.py的内容如下:

from setuptools import setup
from Cython.Build import cythonizesetup(
    name='ros_os',


    ext_modules=cythonize("ros_os.py"),
    zip_safe=False,
)

然后运行指令python setup.py build_ext --inplace,则会在同级目录下生成ros_os.so动态库文件。在其他python文件中,就可以通过import导入该.so文件,实现加速。

注意,若os文件夹下有__init__.py文件,则会出错。解决方法是需要将setup.py移动到与ros_os.py最近的无__init__.py文件的文件夹下,如以下文件树所示:

├── pkg
│   ├── init.py
│   ├── os
│   │   ├── init.py
│   │   └── ros_os.py
└── setup.py

os文件夹下有__init__.py文件,显式地表示os是一个python的包,同样地,pkg下也存在__init__.py文件,因此需要将setup.py放在与pkg同级的目录下,该目录是最靠近ros_os.py的最近的且无__init__.py文件的目录。同时,修改setup.py中对ros_os.py的路径,如下:

from setuptools import setup
from Cython.Build import cythonize

setup(
    name='ros_os',
    ext_modules=cythonize("pkg/os/ros_os.py"),
    zip_safe=False,
)

在setup.py的同级目录下运行编译指令:python setup.py build_ext --inplace,则可以正确编译获得ros_os.so动态文件。

优点:加速python,并达到python加密的效果(推荐的加密手段)

缺点:需要手动编译;少数python内置属性不支持,例如__file__;

3.numba(传言可加速40倍左右)

numba是一个可以加速python大部分模块的库,其原理是将其修饰的函数在第一次运行时先优化并翻译成机器码,而在重复运行时,则直接调用该机器码,因此达到可以媲美C和C++的速度。使用方法如下:

from numba import jit  # 从numba中导入函数jit
import random

@jit(nopython=True)   # jit,numba装饰器中的一种
def monte_carlo_pi(nsamples):
    acc = 0
    for i in range(nsamples):
        x = random.random()
        y = random.random()
        if (x ** 2 + y ** 2) < 1.0:
            acc += 1
    return 4.0 * acc / nsamples

在原始代码中加入第1行和第4行,则可以加速monte_carlo_pi模块(自动将其优化并编译成机器码)。即,要加速哪个函数,就在函数定义前面加上装饰器@jit(nopython=True)。

优点:对numpy和循环语法的加速明显;使用方便;

缺点:少量库无法加速,如pandas库;仅能安装到无法用于python2及以下版本;安装比较困难,需要装llvm编译器;

4.其他加速方法

使用整型代替浮点型

5.各自加速方法的对比

代码片段对大小为128x128的二维数组求和,运行1000次时间如下:

Total cost time for func: py_func, call 1000 times: 3.803216s. 
Total cost time for func: np_func, call 1000 times: 0.343562s. 
Total cost time for func: nb_func, call 1000 times: 0.017122s. 
Total cost time for func: cy_func, call 1000 times: 0.018159s.

它们分别代表了原始Python、Numpy、Numba、Cython对应的性能。可以看出,cython与numba可有效加速python代码。其中,numba以稍微快于cython,但是numba不兼容python2,且调试困难,因此,推荐使用cython。

6.方法补充

下面小编为大家整理了一些其他Python可以加速运行的技巧,希望对大家有所帮助

1.全面加速(pypy)

将python换为pypy,在纯python代码下,pypy的兼容性就不影响使用了,因为一些纯python的代码常常会用pypy进行一下加速

测试代码,for循环10000000次

start = time.time()
for i in range(10000000):
    print(i,end="\r")
end = time.time()
print(f"耗费时间{end-start}秒>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

2.if判断靠前

如:

 if tag in ["nts", "nto", "ntc", "ntcb", "ntcf", "ntch", "nth", "ntu", "nt"]:
                                BMES(f_,i2, tag="ORG")
                            elif tag in ["nb", "nba", "nbc", "nbp", "nf", "nm", "nmc", "nhm", "nh"]:
                                BMES(f_,i2, tag="OBJ")
                            elif tag in ["nnd", "nnt", "nn"]:
                                BMES(f_,i2, tag="JOB")
                            elif tag in ["nr", "nrf"]:
                                BMES(f_,i2, tag="PER")
                            elif tag in ["t"]:
                                BMES(f_,i2, tag="TIME")
                            elif tag in ["ns", "nsf"]:
                                BMES(f_,i2, tag="LOC")
                            else:
                                for i3 in list(i2):
                                    f_.write(i3 + " " + f"O" + "\n")

满足条件的可以先跳出判断

到此这篇关于python代码加速运行的四种方法详解的文章就介绍到这了,更多相关python加速运行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Python 统计高频字数的方法

    使用Python 统计高频字数的方法

    今天小编就为大家分享一篇使用Python 统计高频字数的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • python光学仿真相速度和群速度计算理解学习

    python光学仿真相速度和群速度计算理解学习

    从物理学的机制出发,波动模型相对于光线模型,显然更加接近光的本质;但是从物理学的发展来说,波动光学旨在解决几何光学无法解决的问题,可谓光线模型的一种升级
    2021-10-10
  • python3实现raspberry pi(树莓派)4驱小车控制程序

    python3实现raspberry pi(树莓派)4驱小车控制程序

    这篇文章主要为大家详细介绍了python3实现raspberry pi(树莓派)4驱小车控制程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • Python转码问题的解决方法

    Python转码问题的解决方法

    在Python中,可以对String调用decode和encode方法来实现转码。
    2008-10-10
  • 解决pycharm安装后代码区不能编辑的问题

    解决pycharm安装后代码区不能编辑的问题

    今天小编就为大家分享一篇解决pycharm安装后代码区不能编辑的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • 使用beaker让Facebook的Bottle框架支持session功能

    使用beaker让Facebook的Bottle框架支持session功能

    这篇文章主要介绍了使用beaker让Facebook的Bottle框架支持session功能,session在Python的Django等框架中内置但在Bottle中并没有被集成,需要的朋友可以参考下
    2015-04-04
  • (手写)PCA原理及其Python实现图文详解

    (手写)PCA原理及其Python实现图文详解

    这篇文章主要介绍了Python来PCA算法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能给你带来帮助
    2021-08-08
  • 用 Python 制作地球仪的方法

    用 Python 制作地球仪的方法

    这篇文章主要介绍了如何用 Python 制作地球仪,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考即将价值,需要的朋友可以参考下
    2020-04-04
  • 想学python 这5本书籍你必看!

    想学python 这5本书籍你必看!

    想学python,这5本书籍你必看!本文为大家推荐了学习python的5本书籍,5本经典书籍,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • python基础之停用词过滤详解

    python基础之停用词过滤详解

    这篇文章主要介绍了python基础之停用词过滤详解,文中有非常详细的代码示例,对正在学习python基础的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-04-04

最新评论