社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python太慢?这4个提速神技让你代码快到飞起!

Crossin的编程教室 • 7 月前 • 224 次点击  

大家好,欢迎来到 Crossin 的编程教室。

作为每天都在用 Python 工作的开发者,我最常听到大家的吐槽就是:“Python 写起来是真爽,但跑起来也是真慢!”

尤其是在处理一些大量计算或者跑数据的时候,看着控制台半天不跳下一个进度条,恨不得进去推它一把。

其实,很多时候并不是 Python 不行,而是我们使用的“姿势”不对。今天 Crossin 就来跟大家分享 4 个实战中非常管用的提速技巧,直接上代码!

1. 别再死磕 for 循环了,用 NumPy 降维打击

这是很多刚进阶的同学最容易踩的坑:处理一大堆数据时,下意识地就写个 for 循环遍历。

Python 解释器跑这种原生的 for 循环开销极大。遇到数值计算,能用 NumPy 向量化解决的,绝不用 for 循环。 NumPy 底层是 C 语言,它能一次性把操作打在整个数组上。

标准写法:

import time
def slow_sum(n):    a = list(range(n))    b = list(range(n))    c = []    for i in range(len(a)):        c.append(a[i] + b[i])    return c
# 跑 1000 万次,测测看start = time.time()slow_sum(10**7)print(f"原生循环耗时: {time.time() - start:.2f}s")

加速写法:

import timeimport numpy as np
def fast_sum(n):    a = np.arange(n)    b = np.arange(n)    return a + b
start = time.time()fast_sum(10**7)print(f"NumPy 向量化耗时: {time.time() - start:.4f}s")

运行结果: 

原生循环耗时:1.82s

NumPy 向量化耗时:0.12s

千万级数据下,NumPy 比原生列表循环快了15倍。

2. 实在绕不开循环?加个 @njit 装饰器救命

有些复杂的业务逻辑,比如带有复杂判断条件的数值模拟,真的没法直接用 NumPy 拼出来,必须得写 for 循环怎么办?

这时候,祭出神器 Numba。它是一个 JIT(即时编译器),作用非常粗暴:把你的 Python 函数直接翻译成机器码。

用法超级简单,只需要引入库,并在函数头上加一行 @njit。

标准写法:

import time
def check_logic(n):    res = 0    for i in range(n):        if i % 3 == 0:            res += i    return res
start = time.time()check_logic(10**8)print(f"原生 Python 耗时: {time.time() - start:.2f}s")

加速写法:

import timefrom numba import njit
@njit  # 只需要这一个装饰器def check_logic_fast(n):    res = 0    for i in range(n):        if i % 3 == 0:            res += i    return res
# 第一次运行会有编译时间,之后起飞start = time.time()check_logic_fast(10**8)print(f"Numba JIT 耗时: {time.time() - start:.2f}s")

运行结果: 

原生 Python 耗时: 6.54s

Numba JIT 耗时: 0.42s

Numba 第一次运行时要编译,优化不明显,之后的运行速度大约提升了15倍。

3. 多核 CPU 别闲着,多进程 multiprocessing 跑起来

众所周知,Python 有个叫 GIL(全局解释器锁)的玩意儿,导致单进程下多线程没法同时利用多核 CPU。

如果你需要处理比如:大规模图片压缩、海量文件解析这种“吃 CPU”(计算密集型)的任务,别犹豫,直接上多进程,强行把你的 8 核、10 核 CPU 榨干。

标准写法:

import time
deftask(n):returnsum(i * i for i inrange(n))
start = time.time()[task(10**7) for _ inrange(4)]print(f"单进程顺序执行: {time.time() - start:.2f}s")

加速写法:

import timeimport multiprocessing
deftask(n):returnsum(i * i for i inrange(n))
if __name__ == "__main__":    start = time.time()with multiprocessing.Pool(processes=4) as pool:        pool.map(task, [10**7] * 4)print(f"4进程并行执行: {time.time() - start:.2f}s")

运行结果: 

单进程顺序执行: 3.98s

4进程并行执行: 1.23s

千万级数据下,4进程并行比单进程快了3倍多。

4. 终极偷懒大招:代码一行不改,换 PyPy 跑

如果你上面这些都不想搞,或者这是一个纯粹用 Python 写的庞大项目,有没有“物理外挂”?

有的,直接把执行命令里的 python 换成 pypy。

PyPy 是自带了 JIT 编译器的 Python 替代品。你不需要改动任何一行代码。

举个例子,一个算斐波那契数列的脚本 fib.py:

# fib.pydef fib(n):    if n 2: return n    return fib(n-1) + fib(n-2)
import timestart = time.time()fib(36)print(f"执行耗时: {time.time() - start:.2f}s")

你平时这么跑:python fib.py

执行耗时:3.16s

现在这么跑:pypy3 fib.py

执行耗时:0.21s

纯 Python 代码的逻辑,换个“发动机”,就获得了15倍的速度提升。不过要注意,pypy3运行环境需要额外安装,并且如果你的项目重度依赖某些特定的 C 扩展库,兼容性需要提前测试一下。

总结:

写 Python 遇到性能瓶颈了,可以参考这个思路:

玩数据矩阵:优先想办法用 NumPy。

死磕计算循环:用 Numba 加速试试。

批量粗活累活:开 多进程 一起上。

祖传老代码:丢给 PyPy 碰碰运气。

但也要注意,优化是有成本的,别为了快而快,先把功能实现好。否则过早的优化是万恶之源!

大家平时在写代码时还踩过哪些性能的坑?或者有什么压箱底的优化绝活?欢迎在评论区留言聊聊。

如果本文对你有帮助,欢迎点赞、评论、转发。你们的支持是我更新的动力~


添加微信 crossin123 ,加入编程教室共同学习~
感谢转发和点赞的各位~

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/194369