当前位置: 首页 > 科技观察

5个带你轻松分析Python代码的软件库

时间:2023-03-15 00:02:51 科技观察

【.com快译】通常人们用两种速度来衡量一门编程语言的优劣,即:开发速度和执行速度。对于Python,大家往往受益的是可以快速编写代码,却忽略了是否可以快速运行,及时完成既定任务。因此,当程序运行缓慢时,我们有必要从代码层面找出速度变慢的位置和原因,并进行处理。好消息是Python提供了许多用于不同目的的软件库,这使我们能够分析应用程序代码并找出导致速度缓慢的原因。这些范围从带有标准库的单行代码到从运行程序中收集统计信息的复杂框架。下面,我将向您介绍其中的五个存储库,它们可以在PyPI或Python标准库上轻松获得,并且可以跨平台工作。1.TimeandTimeit有时,你可能只想分析两个代码段从上一个代码段的结尾到下一个代码段的开始所花费的时间是秒还是分钟。对于这样的需求,你可能只需要一块秒表就足够了。Python标准库带有两个可用作秒表的实用函数。其中Time模块有perf_counter函数。可以调用操作系统的高精度定时器按需获取时间戳。基本原理是:我们可以在目标操作开始前调用一次time.perf_counter,等操作完成后再调用一次,获取两次的时间差。显然,这是一种非常简单易行的时间获取方式。Timeit模块是对Python代码的实质性审查。它的timeit.timeit函数会截取一个代码段并运行多次(默认100万次)来获取执行该操作所需的平均时间。我们经常可以用它来确定在紧密循环中调用单个操作或函数的时间。例如,如果你想决定在执行多个操作时是列表理解(listcomprehension)还是常规列表结构更快(列表理解通常更快)。当然,Time的不足之处在于它只是一个秒表,而Timeit的不足之处在于它的主要用例是在单独的行或代码块上进行单独的微基准测试。也就是说,仅当代码被单独处理时,比较才有意义。因此,这两种方法都不足以分析整个程序。一旦你有数千行代码,这两种方法都会花费你很多时间。2.cProfilePython标准库还自带一个整体程序分析器——cProfile。当程序运行时,cProfile会跟踪代码中每个函数的调用,生成一个包含最常调用函数和平均调用时间的列表。cProfile具有三大优势:因为它包含在标准库中,所以现有的Python安装已经包含cProfile。它可以分析有关呼叫行为的许多不同统计数据。例如:它能够区分一个函数调用它自己的指令所花费的时间和所有其他调用该函数所花费的时间。由此可以判断是函数本身慢了,还是其他调用慢了。可以自定义资格条件。也就是说,您可以对整个程序的执行进行采样,也可以仅在指定函数运行时启用分析(切换分析)。通过缩小范围并消除分析时产生的“噪音”,您可以更好地关注函数的作用和调用。cProfile的缺点是:默认情况下,它会设置多个收集点并生成大量统计信息。根据其执行模型,每次捕获函数调用时都会产生大量流量。因此,cProfile不适合通过实时数据对生产环境中的应用进行性能分析。也就是说,它更适合在开发过程中进行分析。有关cProfile的更多详细信息。3.Pyinstrument的工作方式与cProfile类似。Pyinstrument可以通过跟踪目标程序,以报表的形式反映出占用运行时间最多的代码。但与cProfile相比,Pyinstrument的优势主要体现在以下两个方面:Pyinstrument不会hook函数调用的每一个实例,而是以毫秒为间隔对程序的调用栈进行采样,因此可以灵敏地检测程序中最耗时的部分。Pyinstrument的报告要简洁得多。它可以突出显示程序中最耗时的功能,以便您尽快找到问题并集中精力分析原因。Pyinstrument还具有cProfile的各种优点。您可以将它用作应用程序中的对象来记录选定的功能而不是整个程序的行为。Pyinstrument提供了包括HTML格式在内的多种输出形式。当然,您也可以点播查看个别来电的完整时间线。此外,以下两个方面也值得您注意:一些由C编译的扩展(例如使用Cython创建的程序)在命令行调用Pyinstrument时可能无法正常工作。但是,如果您在程序本身中使用Pyinstrument,它们仍然可以工作,例如通过调用Pyinstrument分析器包装main()函数。Pyinstrument不能很好地处理在多线程中运行的代码。此时,你可能要考虑使用Py-spy,下面会介绍。4.py-spy和Pyinstrument是一样的。在工作原理上,Py-spy也周期性地收集程序调用栈的状态,而不是记录每一次调用。不过,与PyInstrument不同的是,Py-spy带有一个用Rust编写的核心组件(而Pyinstrument使用C扩展),与分析器一起在进程外运行,因此它可以安全地在生产中使用代码。Py-spy可以轻松完成许多其他分析工具无法完成的任务,包括:分析多线程或具有子进程机制的Python程序等。此外,Py-spy还可以分析使用符号编译的C扩展程序。对于使用Cython编译的扩展,Py-spy需要使用相应生成的C文件才能收集正确的跟踪信息。我们可以使用以下两种基本方法来检查带有Py-spy的应用程序:使用Py-spy的record命令,运行后生成一个火焰图(flamegraph)。使用Py-spy的top命令以与Unix的top工具相同的方式以交互方式显示具有实时更新和显示信息的Python应用程序的内部结构。而且那些单线程的栈也可以通过命令行显示出来。但是Py-spy最大的缺点之一就是它主要适合从外部分析整个程序或者部分组件,不适合对某个特定的函数进行抽样。5.YappiYappi是YetAnotherPythonProfiler(“另一种Python分析工具”)的缩写。就功能而言,它只比上面讨论的工具库多了很多。默认情况下,PyCharm(译者注:面向专业Python开发者的IDE)会安装Yappi,因此用户已经在IDE中内置了对Yappi的访问。要使用Yappi,您需要使用指令“装饰”目标代码以调用分析机制、启动、停止和生成报告。Yappi允许您根据测试的实际需要在“walltime”或“CPUtime”之间进行选择。前者只是秒表;后者可以通过系统的nativeAPI记录CPU实际执行代码所花费的时间,从而调整I/O的挂起或线程的休眠。由此可见,CPU时间可以方便你更准确地了解某些操作(如数字代码的执行)实际花费的时间。通过Yappi提供的函数--yappi.get_thread_stats(),可以记录任意一个线程的活动,获取相应的统计信息,并分别进行分析。您不仅不需要“修饰”线程代码,还可以对统计信息进行过滤和细粒度排序(类似于您在cProfile中可以做的)。此外,Yappi的独特之处在于它可以分析greenlets和协程(coroutines)。作为分析并发代码的强大工具,它可以广泛用于分析异步隐喻。原标题:5个用于分析Python代码的伟大库,作者:SerdarYegulalp