You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
K_class/developed_code/用 cProfile 找出代码中的性能瓶颈并进行改进.md

78 lines
3.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

## 用 cProfile 找出代码中的性能瓶颈并进行改进
### 1. 背景介绍
在编写和优化 Python 程序的过程中,性能问题是一个不可忽视的环节。程序的性能瓶颈可能隐藏在大量的函数调用和代码执行过程中,尤其是在处理大量数据或进行复杂计算时,性能问题可能会严重影响程序的执行效率。为了找到并解决这些性能瓶颈,性能分析工具如 cProfile 就显得尤为重要。
### 2. cProfile 简介
cProfile 是 Python 内置的性能分析模块它能够跟踪每个函数的调用情况记录函数的执行次数和消耗的时间从而帮助开发者找到代码中的性能瓶颈。cProfile 的优点在于它是标准库的一部分,无需额外安装,且使用简单,功能强大。
### 3. 使用 cProfile 进行性能分析
#### 3.1 代码示例
为了使用 cProfile 进行性能分析,我们可以在项目的主文件中加入以下代码:
```python
import cProfile
import pstats
import a_wordcloud
import bvid
import to_allexcel
import to_danmu
import to_excel
def run_all():
# 在这里调用你希望运行和分析的函数
a_wordcloud.main()
bvid.main()
to_allexcel.main()
to_danmu.main()
to_excel.main()
if __name__ == '__main__':
profiler = cProfile.Profile()
profiler.enable()
run_all()
profiler.disable()
profiler.dump_stats('performance_profile.prof')
# 分析结果
with open('performance_report.txt', 'w') as f:
ps = pstats.Stats(profiler, stream=f)
ps.sort_stats('cumulative')
ps.print_stats()
```
#### 3.2 运行性能分析
在将上述代码添加到项目中之后,运行程序,程序执行结束后会生成两个文件:
- `performance_profile.prof`:保存性能分析数据的二进制文件。
- `performance_report.txt`:包含详细的性能分析报告,包括各个函数的调用次数和执行时间等。
### 4. 性能数据的查看与分析
#### 4.1 打开 `performance_report.txt`
打开生成的 `performance_report.txt` 文件可以看到各个函数的调用次数ncalls、总耗时tottime、自耗时percall、以及累计耗时cumtime等信息。
例如:
```
5001 2.180 0.000 2.180 0.000 {built-in method time.sleep}
```
- `ncalls`: 函数被调用的次数。
- `tottime`: 函数本身消耗的时间,不包括调用其他函数的时间。
- `percall`: `tottime`/`ncalls`,即每次调用的平均耗时。
- `cumtime`: 函数及其调用的所有子函数的总耗时。
#### 4.2 性能瓶颈的分析
通过阅读 `performance_report.txt`,可以轻松地找到消耗时间最多的函数。例如,如果某个函数的 `tottime` 非常高而该函数又频繁调用那么它很可能就是程序的性能瓶颈。其中代码程序在获取bvid号时消耗时间较高这主要是因为我的代码是采用顺序执行的方式即需要爬取完一个视频之后才能继续爬取其他视频。
### 优化方法和结果:
因此我改进的思路是采用多进程并发执行,从而提升运行时间。
以下是前后对比:
![image-20240918025811934](C:\Users\onelastkiss\AppData\Roaming\Typora\typora-user-images\image-20240918025811934.png)
![image-20240918025828605](C:\Users\onelastkiss\AppData\Roaming\Typora\typora-user-images\image-20240918025828605.png)