Python 代码性能优化技巧

定位程序性能瓶颈

分析工具:profile,cProfile,PyCharm工具(简单,方便),还有line_profiler,pprofile

图形化工具:gprof2dot

对保存结果分析:pstats

  1. profile的使用

    profile 的使用非常简单,只需要在使用之前进行 import 即可。具体实例如下:

    import profile
    
    def profileTest():
        num = 1
        for i in range(100):
            num += 1
        return num
    
    if __name__ == '__main__':
        profile.run("profileTest()")
    

    得到的结果如下:

在这里插入图片描述

其中输出每列的具体解释如下:

  • ncalls:表示函数调用的次数;
  • tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
  • percall:(第一个 percall)等于 tottime/ncalls;
  • cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时
  • percall:(第二个 percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
  • filename:lineno(function):每个函数调用的具体信息;

如果需要将输出以日志的形式保存,只需要在调用的时候加入另外一个参数。如 profile.run(“profileTest()”,”testprof”)

  1. cProfile的使用

    相比于其它内置的分析器(profile 或 hotshot),cProfile 对系统的开销更少。

    使用方法非常简单,一条命令即可:

    python -m cProfile test.py
    

    如果要将分析结果保存到文件,则:

    python -m cProfile -o result test.py
    

    输出结果与profile的输出结果一样,参数解释也一样。

  2. PyCharm的工具

    也可以使用PyCharm的工具进行性能分析,而且还可以用图形化的方式查看(专业版PyCharm)。

    如果使用的不是专业版,可以下载专业版进行安装,可自行上网查找免费使用教程

    菜单栏Run -> Profile '[文件名]'即可运行,或者右键 Profile ‘[文件名]’,可得到表格结果以及图形化结果,详细说明见利用PyCharm的Profile工具进行Python性能分析

  3. 工具pstats分析

    对于 profile 和 cProfile 的剖析数据,如果以二进制文件的时候保存结果的时候,可以通过 pstats 模块进行文本报表分析,它支持多种形式的报表输出,是文本界面下一个较为实用的工具。使用非常简单:

    import pstats 
    p = pstats.Stats('testprof') 
    p.sort_stats("name").print_stats()
    

    其中 sort_stats() 方法能够对剖分数据进行排序, 可以接受多个排序字段,如 sort_stats(‘name’, ‘file’) 将首先按照函数名称进行排序,然后再按照文件名进行排序。常见的排序字段有 calls( 被调用的次数 ),time(函数内部运行时间),cumulative(运行的总时间)等。此外 pstats 也提供了命令行交互工具,执行 python – m pstats 后可以通过 help 了解更多使用方式。

  4. line_profiler(未尝试)

    这个分析器可以提供逐行水平的负载信息。这是通过 C 语言用 Cython 实现的,要使用这个工具,你首先需要通过 pip 添加:pip install pip install Cython ipython==5.4.1 line_profiler(CPython2)。你需要在你想分析的函数上加上一个装饰 @profile

        kernprof -l test.py
        python -m line_profiler test.lprof
    
  5. pprofile(未尝试)

    据作者介绍,pprofile 是一个「行粒度的、可感知线程的确定性和统计性纯 Python 分析器。

    它的灵感来源于 line_profiler,修复了大量缺陷,但因为其完全是用 Python 写的,所以也可以通过 PyPy 使用。和 cProfile 相比,使用 CPython 时分析的时间会多 28 倍,使用 PyPy 时的分析时间会长 10 倍,但具有粒度更大的细节水平。

对于line_profile和pprofile想有更多的了解的,可见代码优化指南:人生苦短,我用Python

查找可优化代码
  1. 对于代码中的重复逻辑进行合并
  2. 对代码中的冗余逻辑进行删除
  3. 调用次数最多的语句或者占用时间最长的语句可否使用高效率库进行替换
Python代码优化常见技巧
  1. 数据结构

    列表和字典:Python 字典中使用了 hash table,因此查找操作的复杂度为 O(1),而 list 实际是个数组,在 list 中,查找需要遍历整个 list,其复杂度为 O(n),因此对成员的查找访问等操作字典要比 list 更快。

    如果要查找一个元素在不在列表中,可将列表使用 dict.fromkeys()转换为字典,再进行查找,会快很多。

    列表和集合:set 的 union, intersection,difference 操作要比 list 的迭代要快。因此如果涉及到求 list 交集,并集或者差的问题可以转换为 set 来操作。

  2. 对循环的优化

    对循环的优化所遵循的原则是尽量减少循环过程中的计算量,有多重循环的尽量将内层的计算提到上一层。

  3. 充分利用 Lazy if-evaluation 的特性

    python 中条件表达式是 lazy evaluation 的,也就是说如果存在条件表达式 if x and y,在 x 为 false 的情况下 y 表达式的值将不再计算。因此可以利用该特性在一定程度上提高程序效率。

  4. 字符串的优化

    python 中的字符串对象是不可改变的,因此对任何字符串的操作如拼接,修改等都将产生一个新的字符串对象,而不是基于原字符串,因此这种持续的 copy 会在一定程度上影响 python 的性能。对字符串的优化也是改善性能的一个重要的方面,特别是在处理文本较多的情况下。

    • 在字符串连接的使用尽量使用 join() 而不是 +
    • 当对字符串可以使用正则表达式或者内置函数来处理的时候,选择内置函数。如 str.isalpha(),str.isdigit(),str.startswith((‘x’, ‘yz’)),str.endswith((‘x’, ‘yz’))
    • 对字符进行格式化比直接串联读取要快,因此要使用占位符或者format(),不要使用 + 连接字符串
  5. 使用列表解析和生成器表达式

    列表解析要比在循环中重新构建一个新的 list 更为高效,因此我们可以利用这一特性来提高运行的效率。

    生成器表达式语法和列表解析类似,但是在大数据量处理时,生成器表达式的优势较为明显,它并不创建一个列表,只是返回一个生成器,因此效率较高。

以上介绍的只是对 Python代码本身做优化,当然也可以使用 PyPy或者 Cython将代码转换成其他语言提高效率,有兴趣者可以见参考文章链接。

参考文章

https://www.ibm.com/developerworks/cn/linux/l-cn-python-optim/

https://blog.csdn.net/xiemanR/article/details/69398057?utm_source=copy

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python代码优化是通过一系列技巧和策略来提升代码的运行效率和性能。以下是几个常见的Python代码优化方法: 1. 使用更高效的数据结构和算法:选择适当的数据结构和算法可以显著提高代码的运行速度。例如,使用集合(Set)替代列表(List)可以加快查找和去重操作的速度。 2. 使用更快速的内置函数:Python提供了许多内置函数,它们通常比使用循环实现的同等操作更高效。例如,使用sum()函数来计算列表中的元素总和,而不是使用循环逐个相加。 3. 减少函数调用和循环次数:函数调用和循环是Python中的开销较大的操作,尽量减少它们的使用可以提高代码的性能。可以通过合并循环或使用生成器来减少循环次数,或者将重复的代码块提取为函数以减少函数调用次数。 4. 使用列表推导式:列表推导式是一种简洁而高效的创建列表的方式。它可以在一行代码中完成循环和条件判断,并生成一个新的列表。使用列表推导式可以减少代码量并提高代码的可读性和运行效率。 5. 慎重使用循环和递归:循环和递归是实现算法的常用方式,但它们也是耗时的。在使用循环和递归时,要确保算法的时间复杂度是可接受的,并避免出现无限循环或递归的情况。 6. 利用并行计算:对于一些计算密集型任务,可以通过使用并行计算来提高代码的运行速度。Python提供了多线程和多进程的模块,可以利用多核处理器的能力来同时执行多个任务。 综上所述,Python代码优化是通过选择更高效的数据结构和算法、减少函数调用和循环次数、使用列表推导式等方法来提高代码的运行效率和性能。可以根据具体的需求和场景选择适合的优化方法来优化Python代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python 代码性能优化](https://blog.csdn.net/Herishwater/article/details/99656200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [10条Python代码优化技巧](https://blog.csdn.net/qq2480303715/article/details/125973733)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CharlesWu123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值