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万美元就能处理等量的负荷。