并发、异步与性能
并发、异步与性能
先写正确,再写清楚,最后再优化性能。
性能判断
优化前先回答:
- 程序慢在哪里?
- 是 CPU 计算慢,还是 I/O 等待慢?
- 数据量会增长到多大?
- 有没有简单算法改进?
计时
1 | from time import perf_counter |
更系统可以用:
timeitcProfileline_profiler
GIL
Python 的全局解释器锁会影响多线程执行 CPU 密集任务。
简单理解:
- I/O 密集:线程或异步通常有效。
- CPU 密集:考虑多进程、向量化、C 扩展或换算法。
threading
适合:
- 网络请求。
- 文件 I/O。
- 等待外部服务。
1 | from threading import Thread |
concurrent.futures
更推荐的统一接口。
1 | from concurrent.futures import ThreadPoolExecutor |
进程池:
1 | from concurrent.futures import ProcessPoolExecutor |
asyncio
适合大量 I/O 等待任务。
1 | import asyncio |
关键词:
async defawaitasyncio.gatherasyncio.create_task- event loop
锁与队列
并发共享状态时要谨慎。
常见工具:
LockQueueSemaphoreEvent
性能常见方向
- 换更好的算法。
- 减少重复 I/O。
- 使用缓存。
- 批量处理。
- 使用生成器节省内存。
- 用 NumPy/Pandas 向量化。
- 把热点代码交给成熟库。
常见坑
- 以为多线程一定更快。
- 忘记等待任务结束。
- 异步函数里调用阻塞 I/O。
- 多进程传输大对象导致额外开销。
- 没有测量就优化。
练习
- 用线程池并发请求多个 URL。
- 用进程池计算一批 CPU 密集任务。
- 用
asyncio.gather并发等待多个任务。 - 用
cProfile找出脚本最慢的函数。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Kalax524!