提高 Python 性能的 9 个技巧

与 Java 等语言相比,Python 的性能较差。使用这些技巧来识别和修复 Python 代码中的问题,以调整其性能。

优化的应用程序和网站从构建良好的代码开始。然而,事实是您不需要担心 90% 的代码的性能,对于许多脚本来说可能是 100%。如果 ETL 脚本只运行一次或每晚运行一次,那么它花费一秒或一分钟并不重要。

不过,如果用户被迫等待缓慢的应用程序完成任务或网页显示结果,这确实很重要。即便如此,也可能只有代码库的一小部分应该受到指责。

最大的性能优势通常来自于编码甚至开始之前的性能规划,而不是在性能缓慢发生之后。也就是说,应用程序开发人员可以通过多种方式解决代码性能问题。

以下九个技巧专门针对Python 性能,尽管其中一些技巧也适用于其他语言:

  1. 选择正确的数据类型。

  2. 了解标准函数、方法和库。

  3. 查找注重性能的库。

  4. 理解不同的理解。

  5. 使用生成器函数、模式和表达式。

  6. 考虑如何处理大数据。

  7. 运行配置文件来识别有问题的代码。

  8. 考虑 CPython 替代品。

  9. 专注于有意义的改进。


文章来源地址https://www.toymoban.com/diary/python/364.html

选择正确的数据类型

使用集合的最佳数据类型。只要有集合,就可以轻松创建列表。您几乎可以在任何地方使用列表来代替集合或元组,并且列表的作用远不止这些。

但是,使用集合或元组进行某些操作会更快,并且这两种类型通常比列表使用更少的内存。要选择用于集合的最佳类型,您必须首先了解您正在使用的数据以及要执行的操作。

使用timeit我们可以看到使用集合测试成员资格比使用列表测试要快得多:

> python testtimeit_data_type.py

执行时间(带列表):7.966896300087683秒

执行时间(带设置):4.913181399926543秒

有时从列表创建临时集或元组会更快。例如,要查找两个列表中的公共值,创建两个集合并使用set junction()可能会更快。这取决于数据长度和操作,因此最好使用您期望的数据和操作进行测试。

了解标准函数、方法和库

了解 Python 的标准功能。模块经过优化,几乎总是比您编写的代码更快。许多 Python 函数很少需要,而且很容易忘记它们的存在。您可能记得set intersection() ,但是如果您需要它们,您会记得Difference()或isdisjoint()吗?

偶尔浏览一下Python 文档(https://docs.python.org/3/library),或者当您遇到性能问题时,了解哪些功能可用。当您开始一个新项目时,请仔细阅读与您自己的工作相关的那些部分。

如果您只有时间研究一个模块,请将其设为itertools——如果您认为可以使用它的功能,请考虑安装more-itertools(https://github.com/more-itertools/more-itertools)(标准库中没有)。itertools 的一些功能乍一看可能没什么用,但如果您正在从事某些工作并记住您在 intertools 中看到的可以提供帮助的内容,请不要感到惊讶。即使您没有看到立即使用,也最好知道有什么可用。

查找注重性能的库

如果您正在做一些大事,那么很可能有人已经创建了一个性能良好的库来帮助您。您可能需要多个库来为项目的不同区域提供功能,其中可能包括以下部分或全部内容:

  • 科学计算。

  • Vision

  • 机器学习。

  • 报告。

  • 整合。

注意发布日期、文档、支持和社区。较旧的库的性能可能不再像以前那样好,并且您可能需要熟悉给定库的人员的帮助才能实现所需的性能。

多个库通常提供相同的功能集。要确定选择哪一个,请使用适合您需求的数据为每个测试创建一个快速测试。您可能会发现其中一个更容易使用,或者另一个提供更好的开箱即用性能。

熊猫 Pandas

Pandas 是初学者常用的数据分析库。它值得学习的原因有两个:其他库使用它或提供兼容的接口,并且您可以找到它的最多帮助和示例。

北极星 Polars

pandas 的替代品(例如 Polars)为许多操作提供了更好的性能。Polars 具有不同的语法,可能会带来学习曲线,但值得一看,以启动新的大数据项目或解决现有项目中的性能问题。

Dask

如果您经常处理非常大的数据,您还应该考虑并行计算。这可能需要更改组织数据和执行计算的方式。它还需要付出大量的努力才能为多核或多台机器正确编程,这是 Python 与其他语言相比落后的领域。

Dask (https://docs.dask.org/)以及其他库(例如 Polars)可以处理复杂性,以充分利用您的核心或机器。如果您熟悉 NumPy 或 pandas,Dask 提供了跨内核并行化的最小学习曲线。即使您不使用 Dask,了解它提供的功能以及如何使用它也很有帮助,可以帮助您做好处理大数据的准备。

理解不同的理解

这是一个常见的 Python 性能技巧:列表理解将比for循环更快。

我的测试得出了这些时间,令人印象深刻。

>python timeit_compressive.py

执行时间(使用 for):5.180072800023481秒

执行时间(使用列表理解):2.5427665999159217秒

但我所做的只是创建一个新列表,其中包含根据原始值计算的值,因为提示通常显示以下内容:

new_list = [val*2 for val in orig_list]

相关问题是:我将如何处理该列表?列表推导式的任何实际性能增益可能来自使用可选谓词(过滤器)、嵌套推导式或生成器表达式而不是列表推导式。

此示例使用嵌套推导式展平矩阵,其性能通常优于嵌套循环:

flattened = [x for row in matrix for x in row]

这个使用嵌套理解和过滤器:

names = [

employee.name

for manager in managers

for employee in employees

    if employee.manager_id == manager.id

]

对列表理解的引用是最常见的,但集合理解、字典理解和生成器表达式的 工作方式相同。为您要创建的数据类型选择正确的类型。

以下示例与上面的矩阵示例类似,但返回一个集合而不是列表,这是从列表中获取唯一值的简单方法。

unique = {x for row in matrix for x in row}

列表理解和集合理解之间的唯一区别是集合理解使用大括号 {} 而不是方括号 []。

使用生成器函数、模式和表达式

生成器是在迭代大型集合时减少内存的好方法。如果您使用大型集合,您应该知道如何编写生成器函数并将生成器模式用于可迭代。

另外,学习如何使用生成器表达式,类似于列表推导式。以下代码对矩阵中所有值的平方求和,而不创建平方列表。

total = sum(x**2 for row in matrix for x in row)

考虑如何处理大数据

大数据和大文件的性能值得进行完整且单独的讨论。也就是说,在开始大数据项目之前需要考虑一些事情。准备做出以下决定:

  • 选择一个数据库。

  • 分块处理数据。

  • 确定是否可以忽略某些数据。

  • 指定数据类型。

  • 使用不同的文件类型。

数据库

对于非常大的数据,您几乎肯定会使用专门的库,例如用于科学计算的 NumPy、用于数据分析的 pandas 或用于并行化和分布式计算的 Dask。搜索互联网,您可能会找到满足任何其他大数据需求的库,以及这些需求的替代方案。

块数据

如果您的数据太大而无法放入 RAM,您可能需要分块处理。这种能力内置于 Pandas 中,如下所示:

chunk_readers = pandas.read_csv("./data.csv", chunksize=2000)

for chunk in chunk_readers:

    for index, record in chunk.iterrows():

            pprint(record)

其他模块(例如 Dask 和 Polars)有自己的数据分块或分区方法。

忽略数据

数据文件中的数据通常比您需要的多得多。Pandas 的read_csv有一个参数usecols,它可以让您指定所需的列,并忽略其余的列:

# 只保留命名列

data_frame = pandas.read_csv("./sales.csv", usecols=["product_id", "zip_code"])
#只保留索引为 1,8 和 20 的列

data_frame = pandas.read_csv("./population.csv", usecols=[1,8,20])

这可以显着减少处理数据所需的内存。.csv 文件对于 RAM 来说可能太大,但如果您只加载所需的列,则可能会避免分块。

推导式是从表中删除列和行的另一种方法,以便您仅使用所需的数据。为此,必须读取整个文件或对整个文件进行分块,并且原始容器和理解容器必须同时存在。如果需要忽略大量行,最好在迭代块时删除行。

指定数据类型

另一种节省内存的方法是指定一次数据类型并使用所需的最小类型。这还可以提高速度,因为它将数据保留为计算最快的格式,并且无需在每次使用数据时转换数据。例如,一个人的年龄适合八位(0-255),因此我们可以告诉 pandas在该列中使用int8而不是int64 :

data_frame = pandas.read_csv("./people.csv", dtype={"age": "int8"})

通常最好在加载期间设置数据类型,但有时这是不可能的——例如,pandas 无法将非整数浮点数(例如 18.5)转换为int8。它可以在加载数据框后转换整个列。Pandas 有多种方法来替换或修改列以及处理数据中的错误:

data_frame['age'] =

            data_frame['age'].astype('int8', errors='ignore')

Dataframe astype和pandas.to_numeric可以执行不同类型的转换。如果这些不适用于您的数据,则可能需要在循环或理解中实现您自己的转换。

使用不同的文件类型

大多数情况要求您使用常见的文件类型,例如 .csv。如果您需要在处理过程中保存中间文件,那么使用其他格式会很有帮助。

Apache Arrow 提供 Python 与PyArrow 模块的绑定。它与 NumPy、pandas 和 Python 对象集成,并提供了以其他文件格式读取和写入数据集的方法。这些格式更小,PyArrow 可以比 Python .csv 函数更快地读取和写入它们。PyArrow 还具有用于数据分析的附加功能,您现在可能不需要这些功能,但至少您知道它可以在将来需要时使用。

如前所述,Pandas 是一个流行的数据分析库。Polars 支持多种文件格式、多核和大于内存的数据文件。Dask 分区处理前面提到的大于内存数据文件的分块,并且 Dask 最佳实践在 Parquet 中使用更高效的文件格式。

运行配置文件以识别有问题的代码

当您遇到性能问题时,最好分析您的代码,而不是猜测优化工作的重点。提高性能的一般方法包括以下步骤:

  1. 创建一个比预期慢的最小的、可重现的用例。

  2. 运行配置文件。

  3. 改进具有最高percall 值的函数。

  4. 重复步骤 2,直到达到所需的性能水平。

  5. 运行一个真实的用例(不是最小的)而不进行分析。

  6. 重复步骤 1,直到达到步骤 5 中所需的性能水平。

凭借经验,您将逐渐了解或至少感受到最佳的聚焦位置。它可能不是具有最高percall值的代码。有时解决方法是修改循环内的单个计算。其他时候,您可能需要消除循环或在循环之外执行计算/理解。也许答案是重新组织数据,或者使用Dask进行并行化。

考虑 CPython 替代品

最常用的 Python 实现是 CPython。所有通用库都可与 CPython 一起使用,并且它完全实现了语言规范。

存在其他实现,但可能会导致以下问题:

  • Python 代码在边缘情况下的行为可能有所不同。

  • C API 模块可能无法工作或工作速度显着变慢。

  • 如果您将来必须运行 CPython,则附加功能将无法使用。

尽管存在这些警告,但在某些情况下,替代实现可能是最好的。如果计算严重依赖于 NumPy 等 C API 模块,那么性能几乎永远不会更好。考虑 CPython 的替代方案,例如:

  • Jython  在 JVM 中运行并允许与 Java 类和对象轻松集成。

  • IronPython 专为 .NET 设计,可轻松与 .NET 生态系统和 C# 库集成。

  • PyPy 使用即时 (JIT) 编译器,除非涉及 C API,否则运行速度明显快于 CPython。

如果您对通用模块(尤其是 C API 模块)的需求非常有限,那么这些和其他 CPython 替代方案值得考虑。如果您的应用程序对现有 Java 或 .NET 功能有很大依赖性,那么 Jython 和 IronPython 是不错的选择。

专注于有意义的改进

还有其他常见建议的提示和技巧可用于提高 Python 性能,例如:

  • 避免点符号,包括Math.sqrt()或myObj.foo()。

  • 使用字符串操作,例如join()方法。

  • 采用多项分配,例如a,b = 1,2。

  • 使用@functools.lru_cache装饰器。

如果您创建timeit测试,当将无效实践与理想实践进行比较时,您会看到巨大的改进。(顺便说一句,您应该学习如何使用timeit。)但是,如果同时满足以下两个条件,这些技巧只会对您的程序产生明显的影响:

  1. 编码已经以“错误的方式”完成,例如在大循环或理解中。

  2. 这些操作每次迭代都会花费大量时间。

如果循环的每次迭代只花费一秒钟,您可能不会注意到在一个语句中执行两个赋值所节省的一小部分时间。

考虑一下您的 Python 优化工作在哪些方面最重要。如果您关注可读性和一致性而不是性能,您可能会获得更多价值。如果你的项目标准是合并作业或消除点,那就去做吧。否则,请坚持使用标准,直到运行性能测试(timeit或profile)并发现问题。



到此这篇关于提高 Python 性能的 9 个技巧的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

原文地址:https://www.toymoban.com/diary/python/364.html

如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用
上一篇 2023年10月07日 21:54
下一篇 2023年10月07日 22:20

相关文章

  • Spark性能优化:提高计算速度与资源利用率的实用技巧

    Apache Spark是一个开源的大规模数据处理框架,它可以处理批量数据和流式数据,并提供了一个易用的编程模型。Spark的核心组件是Spark引擎,它负责执行用户的计算任务。在大规模数据处理中,Spark性能优化是非常重要的,因为它可以提高计算速度和资源利用率。 在本文中,我

    2024年02月20日
    浏览(57)
  • 提高代码效率的6个Python内存优化技巧

    当项目变得越来越大时,有效地管理计算资源是一个不可避免的需求。Python与C或c++等低级语言相比,似乎不够节省内存。 但是其实有许多方法可以显著优化Python程序的内存使用,这些方法可能在实际应用中并没有人注意,所以本文将重点介绍Python的内置机制,掌握它们将大

    2024年01月18日
    浏览(42)
  • 提高 React 性能的技巧

    1.解决重复渲染问题 我们大多数人都知道虚拟 DOM 是如何工作的,但最重要的是检测何时触发树比较。当我们可以跟踪它时,我们可以控制组件的重新渲染,并最终防止意外的性能流。令人惊讶的是,它并不难捕捉。首先,将 React Devtool 扩展添加到浏览器。 然后打开浏览器开

    2024年02月09日
    浏览(71)
  • MYSQL | 提高SQL性能的技巧

      写SQL是开发人员的经常要面对的,考虑SQL的性能是非常重要的: 提升查询效率:   SQL查询的性能直接影响系统的响应时间。优化SQL可以减少查询的执行时间,提高系统的响应速度,提升用户体验。 减少系统负载:   性能低下的SQL语句可能会占用大量的系统资源,导

    2024年02月16日
    浏览(37)
  • Spring Cache:提高应用性能的策略和技巧

    🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页 ——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通Golang(基础

    2024年02月09日
    浏览(44)
  • 深度学习模型优化:提高训练效率和精度的技巧

    🎉欢迎来到AIGC人工智能专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:AIGC人工智能 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如

    2024年02月11日
    浏览(45)
  • CSS 提高性能的方法,并提供一些实用的技巧和代码示例

    CSS 是前端开发中不可或缺的一部分,它负责网页的样式和布局。随着网站规模和复杂度的增加,CSS 的性能也变得越来越重要。本文将介绍 CSS 提高性能的方法,并提供一些实用的技巧和代码示例。 使用压缩后的 CSS 文件 压缩 CSS 文件可以减小文件大小,加快加载速度。常见的

    2024年02月06日
    浏览(55)
  • 矩阵表达的算法优化:线性映射提高性能

    随着大数据时代的到来,数据量的增长日益庞大,传统的算法和计算方法已经无法满足业务需求。为了更高效地处理大规模数据,人工智能科学家和计算机科学家们不断发展出各种新的算法和技术。在这里,我们将关注矩阵表达的算法优化,以及如何通过线性映射提高性能。

    2024年02月21日
    浏览(37)
  • web 各个优化指标,提高你得网站性能,以及动画性能

    名称 简写 含义 优化点 造成常见原因 如何改善 Largest Contentful Paint LCP Web 页主要内容的加载速度,衡量加载体验:为了提供良好的用户体验, LCP 应该在页面首次开始加载后的 2.5 秒内发生。 1,img元素 2,image中的svg元素 3,video元素 4,通过url函数加载背景图片的元素 5,包含

    2024年02月13日
    浏览(39)
  • 优化 RDMA 代码的建议和技巧-rdma性能优化技巧-避坑指南

    DMA 代表直接内存访问。这意味着应用程序可以在 CPU 干预的情况下直接访问(读/写)主机内存。如果您在主机之间执行此操作,它将成为远程直接内存访问 (RDMA) 在阅读有关 RDMA 的内容时,您会注意到一些用于描述其优点的术语。 “零复制 Zero Copy”、“内核绕过 Kernel Bypas

    2024年02月03日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包