github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/translations/debug_python_with_pyroscope.ch.md (about) 1 # 如何使用性能分析来调试Python的性能问题 2 ## 使用火焰图找出问题根源 3 4 以本人经验来讲,在Python服务器上调试性能上的问题可令人沮丧。通常,流量的增加或暂时的故障都可能导致终端用户提交错误报告。 5 通常,因为基本不可能复现故障场景,所以很难找出是哪一部分代码或者架构导致了服务器的性能问题。 6 本文介绍如何使用火焰图持续剖析你的代码,并准确定位是哪些代码导致的性能问题。 7 8 9 ## 为什么你必须关心中央处理器性能 10 通常公司使用云端(如AWS,谷歌云端等)运行软件时会将中央处理器的利用率作为程序性能的一个指标。 11 12 实际上,Netflix高级性能架构师Brendan Gregg提到过:如果,中央处理器利用率能下降1%就是一个很大的胜利,因为这样就能节省很多资源。不管怎样,较小的公司也可看到提升性能的好处。因为无论大小,在软件运行时,中央处理器时常与以下两个重要方面直接相关: 13 1.服务器的花费 : 所需的中央处理器资源越多,运行服务器的成本越高。 14 2.终端用户经验 : 服务器的中央处理器负荷越大,网站或服务器的运行速度越慢。 15 16 因此,当你看到如下中央处理器利用率图表时: 17 ![image](https://user-images.githubusercontent.com/23323466/105662478-aa40ce80-5e84-11eb-800a-57735c688fc9.png) 18 19 在中央处理器利用率为100%,你可假设: 20 - 终端用户的经验并不好(如:应用程序/网站加载速度很慢) 21 - 配置新服务器处理额外负荷后,服务器成本将增加 22 23 关键是:**哪部分代码增加了中央处理器的利用率?** 火焰图这时就派上了用场! 24 25 ## 如何使用火焰图调试性能问题(并在服务器上节省下6.6万美元) 26 假设下面的火焰图对应呈现上图中央处理器利用率飙升的时段。在此高峰期间,服务器的中央处理器的使用情况如下: 27 - `foo()`消耗的时间是75% 28 - `bar()`消耗的时间是25% 29 - 10万美元的服务器成本 30 31 ![pyro_python_blog_example_00-01](https://user-images.githubusercontent.com/23323466/105620812-75197b00-5db5-11eb-92af-33e356d9bb42.png) 32 33 你可把火焰图视为超详细的饼图,其中: 34 - 火焰图的宽度代表着整个时段 35 - 每个节点代表一个功能 36 - 最大的节点占用了大部分中央处理器资源 37 - 每个节点被其上方的节点调用 38 39 在这种情况下,`foo()`占据了整时间范围的75%,因此我们可以改进`foo()`及其调用的函数来减少中央处理器的利用率(并节省$$)。 40 41 ## 用Pyroscope工具创建火焰图和表格 42 为了用代码重现上文的例子,我们将使用Pyroscope工具 — 专门针对性能调试问题提供持续的性能分析,并且是开源。 43 为了模拟服务器,我写了 `work(duration)` 函数,该函数在该持续时间段内模拟工作。这样,我们就可以通过下述代码构建火焰图,来复现`foo()` 所用的75%时间和 `bar()` 所用的25%时间: 44 45 46 <img width="897" alt="foo_75_bar_25_minutes_30" src="https://user-images.githubusercontent.com/23323466/105665338-acf2f200-5e8b-11eb-87b7-d94b7bdda0fc.png"> 47 48 49 ```python 50 # 模拟每次迭代中央处理器的时间 51 def work(n): 52 i = 0 53 while i < n: 54 i += 1 55 56 # 模拟中央处理器运行7.5秒 57 def foo(): 58 work(75000) 59 60 # 模拟中央处理器运行2.5秒 61 def bar(): 62 work(25000) 63 ``` 64 然后,假设你进行了代码优化,把 ‘foo()’ 的时间从75,000降到8000,但其它代码不变。新代码及火焰图所示如下: 65 66 <img width="935" alt="foo_25_bar_75_minutes_10" src="https://user-images.githubusercontent.com/23323466/105665392-cd22b100-5e8b-11eb-97cc-4dfcceb44cdc.png"> 67 68 ```python 69 # 模拟中央处理器运行0.8秒 70 def foo(): 71 # work(75000) 72 work(8000) 73 74 # T 75 def bar(): 76 work(25000) 77 ``` 78 ## 优化`foo()`为我们节省了6.6万美金 79 火焰图帮助我们能立即发现`foo()`是我们代码中的瓶颈。进行优化之后,我们大幅降低中央处理器的利用率。 80 81 ![image](https://user-images.githubusercontent.com/23323466/105666001-1a535280-5e8d-11eb-9407-c63955ba86a1.png) 82 83 84 这代表你的中央处理器的总利用率下降了66%。若你之前为了服务器支付10万美元,那现在只需要3.4万美元就能处理等量的负荷。