Python中优化代码性能的最佳实践

 Python 应用程序性能的首选策略是什么?无论是利用库、优化算法还是利用高级功能,下面是编写高效 Python 代码的技术见解和最佳实践:

使用 functools.cache 或 functools.lru_cache 进行记忆化(这对于将重复调用函数的递归函数和纯函数很有用)。

  1. 如果程序由于同步而缓慢,请使用异步或线程(取决于应用程序/程序)。
  2. 使用 itertools 替换嵌套循环(例如,使用 itertools.product 代替两个嵌套循环)。
  3. 使用 functools.reduce 而不是循环来进行本质上“累积”的转换。
  4. 使用 IO 库中的 BytesIO,而不是连接字节或使用字节数组。
  5. 要减少内存使用,请使用 __slots__。
  6. 如果任务/函数的结果不相互依赖并且不需要顺序执行,请使用多处理。
  7. 如果任务本身很慢,但可以通过在问题上投入更多核心来加快速度,请使用多处理。
  8. 使用可以节省内存的生成器表达式。
  9. 如果其他所有内容都已优化,请使用 PyPy 而不是 CPython。

=================================================
如果有运行数百万条数据记录的循环。我可能需要的唯一优化是优化该循环内发生的事情,因为该代码运行了数百万次。该循环之外的任何代码优化都是不值得的。

=================================================
 python 中进行分析的好方法:

  • 推荐scalene
  • 建议使用 py-spy,并将输出火焰图插入 speedscope
  • PyCharm 有一个内置剖析器(不过社区版本中没有)

==================================================

  • 1) 配置文件
  • 2) 向量化(使用 C 循环)
  • 3) 如果需要更多,Cython/numba
  • 4) 如果需要更多,C/ctypes
  • 5) 如果需要更多,CUDA/ctypes(取决于问题)

每一步都需要成倍增加的时间。我是从科学计算的角度来写的。我假设你已经在使用最好的库来完成这项工作(numpy、pytorch、casadi 等)

如果 pycuda 还不够(例如在多个内核执行之间来回),您可能需要研究nvidia warp

=====================================================
通常从主调用函数开始,使用行分析器以一种肮脏的方式找出占用大部分时间的内容。

多次使用这种方法,对有问题的函数进行简单的矢量化可以获得令人难以置信的速度提升。

就在前几天,我通过直接在 Numpy 中使用智能矢量化进行操作,将一个函数从 17 秒缩短到 20 毫秒。

=====================================================
我最近遇到一个 API 调用问题,该调用需要花费太多时间才能完成。我发现这与在应用程序级别聚合数据时进行的多个数据库调用有关。通过在数据库级别进行计算/聚合解决了问题。计划添加缓存以进一步减少时间

=====================================================
我从事网络工作,所以我的回答有特定的视角。首先要找到真正的瓶颈。优化除实际瓶颈之外的任何内容都是在浪费时间。
此外,性能优化是可读性和性能之间的选择。因此,只有在真正重要的时候才更喜欢性能。
N+1 是 ORM 的常见问题。一般来说,太多的数据库调用可能会出现问题。实际上,数据库是我在网络方面的主要问题。
我遇到过一些情况,我必须对一个大列表执行某些操作,最终我进行了二进制搜索来查找排序数组上的对象,而不是每次都在未排序的数组上搜索。有一个理论然后进行测试是值得的。你的。改变甚至可能不会跑得更快

====================================================
主要是多线程/异步。我可以的地方进行多处理。
多处理仅对可并行化的 CPU 密集型任务有真正的帮助。不幸的是,Python 的实现确实不是很好,并且在很多情况下,多重处理会带来收益递减。

=====================================================
我使用 Python 来实现 ML 库、硬件库、第三方 API 库、原型设计、偶尔运行的 cron 作业等。
如果我正在设计一个实时服务,我会考虑延迟和每秒请求数之类的问题,Python 甚至不会进入我的视野。我可以在 Node 或 PHP 或其他东西上偷懒,但仍然比勤奋的 Python 为我完成某些任务带来的性能好一个数量级。