国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

Python 性能分析器入門教程

2025-07-02 12:03 更新

Python 編程過程中,性能分析是一個至關(guān)重要的環(huán)節(jié)。性能分析可以幫助我們找出程序中的瓶頸,從而優(yōu)化代碼,提高程序的運行效率。Python 標準庫提供了 cProfileprofile 模塊來實現(xiàn)確定性性能分析。本文將深入淺出地為您介紹這兩個模塊的使用方法,讓您輕松掌握 Python 性能分析技巧。

確定性性能分析 是指監(jiān)控程序中所有的函數(shù)調(diào)用、函數(shù)返回和異常事件,并精確計時這些事件之間的時間間隔。與統(tǒng)計分析相比,確定性分析能夠提供更詳細、準確的運行時統(tǒng)計信息,幫助我們更好地了解程序的性能狀況。

一、cProfileprofile 模塊簡介

Python 提供了兩種性能分析模塊:

  1. cProfile :這是一個 C 擴展插件,具有較低的運行開銷,適合分析長時間運行的程序。它基于 lsprof 開發(fā),是大多數(shù)用戶的首選。
  2. profile :這是一個純 Python 模塊,雖然運行開銷較大,但更易于擴展和定制。如果需要對分析器進行深入的二次開發(fā),這個模塊會更加合適。

通常情況下,我們推薦使用 cProfile 模塊,因為它在性能分析過程中對程序運行的影響較小。

二、性能分析基礎(chǔ)操作

1. 分析單個函數(shù)

以下是使用 cProfile 模塊分析單個函數(shù)的簡單示例:

import cProfile
import re
cProfile.run('re.compile("foo|bar")')

執(zhí)行上述代碼后,將輸出類似于以下的分析結(jié)果:

214 function calls (207 primitive calls) in 0.002 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
    1 0.000 0.000 0.002 0.002 {built-in method builtins.exec}
    1 0.000 0.000 0.001 0.001 <string>:1(<module>)
    1 0.000 0.000 0.001 0.001 __init__.py:250(compile)
    1 0.000 0.000 0.001 0.001 __init__.py:289(_compile)
    1 0.000 0.000 0.000 0.000 _compiler.py:759(compile)
    1 0.000 0.000 0.000 0.000 _parser.py:937(parse)
    1 0.000 0.000 0.000 0.000 _compiler.py:598(_code)
    1 0.000 0.000 0.000 0.000 _parser.py:435(_parse_sub)

結(jié)果解讀

  • 第一行顯示共有 214 次函數(shù)調(diào)用,其中 207 次為原始調(diào)用(非遞歸調(diào)用)。

  • 第二行表示輸出結(jié)果是按照累計時間(cumulative time)排序的。

  • 各列含義如下:

    • ncalls :函數(shù)調(diào)用次數(shù)。
    • tottime :在該函數(shù)中執(zhí)行所花費的總時間(不包括調(diào)用子函數(shù)的時間)。
    • percalltottimencalls 的比值,表示每次調(diào)用該函數(shù)的平均時間。
    • cumtime :該函數(shù)及其所有子函數(shù)的累計執(zhí)行時間。
    • percallcumtime 與原始調(diào)用次數(shù)的比值。
    • filename:lineno(function) :函數(shù)所在的文件名、行號和函數(shù)名。

2. 保存分析結(jié)果

如果不想直接打印分析結(jié)果,可以將其保存到文件中,以便后續(xù)分析:

import cProfile
import re
cProfile.run('re.compile("foo|bar")', 'restats')

此時,分析結(jié)果會被保存到名為 restats 的文件中。之后可以使用 pstats.Stats 類來讀取和處理這些結(jié)果。

3. 命令行分析

cProfileprofile 模塊還可以作為腳本直接調(diào)用,用于分析其他腳本的性能。例如:

python -m cProfile [-o output_file] [-s sort_order] (-m module | myscript.py)
  • -o output_file :將性能分析結(jié)果保存到指定文件中,而不是輸出到標準輸出。
  • -s sort_order :指定排序方式,例如按時間排序(time)、按累計時間排序(cumulative)等。
  • -m module :指定要分析的模塊而不是腳本。

三、pstats.Stats 類的使用

pstats.Stats 類提供了豐富的功能,用于分析和格式化性能分析結(jié)果。

1. 基本讀取和打印

import pstats
from pstats import SortKey
p = pstats.Stats('restats')
p.strip_dirs().sort_stats(-1).print_stats()
  • strip_dirs() :從函數(shù)文件名中移除多余的路徑信息,使輸出更簡潔。
  • sort_stats(-1) :對分析結(jié)果進行排序,-1 表示按標準名稱排序。
  • print_stats() :打印分析結(jié)果。

2. 按不同條件排序

可以按不同的條件對分析結(jié)果進行排序,以便更直觀地了解程序性能。

p.sort_stats(SortKey.NAME)
p.print_stats()

此代碼按函數(shù)名稱排序并打印結(jié)果。

p.sort_stats(SortKey.CUMULATIVE).print_stats(10)

此處按累計時間排序,并打印前 10 行結(jié)果,有助于快速定位程序中的性能瓶頸。

p.sort_stats(SortKey.TIME).print_stats(10)

按每個函數(shù)自身的執(zhí)行時間排序,同樣顯示前 10 行。

3. 篩選和查找

可以根據(jù)特定條件篩選分析結(jié)果,例如:

p.sort_stats(SortKey.FILENAME).print_stats('__init__')

按文件名排序,并打印所有包含 __init__ 的函數(shù)的分析結(jié)果。

p.sort_stats(SortKey.TIME, SortKey.CUMULATIVE).print_stats(.5, 'init')

先按時間排序,再按累計時間排序,打印出原始結(jié)果 50% 的數(shù)據(jù)中包含 init 的相關(guān)函數(shù)信息。

還可以查看函數(shù)的調(diào)用者和被調(diào)用者:

p.print_callers(.5, 'init')

顯示調(diào)用了包含 init 的函數(shù)的調(diào)用者列表。

p.print_callees()

打印被指定函數(shù)調(diào)用的所有函數(shù)列表。

四、profile.Profile 類的使用

在需要更精確地控制性能分析過程時,可以直接使用 profile.Profile 類。

1. 基本性能分析

import cProfile, pstats, io
from pstats import SortKey
pr = cProfile.Profile()
pr.enable()
# 在這里執(zhí)行要分析的代碼
pr.disable()
s = io.StringIO()
sortby = SortKey.CUMULATIVE
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())
  • enable() :開始收集性能分析數(shù)據(jù)。
  • disable() :停止收集數(shù)據(jù)。

也可以使用上下文管理器來簡化代碼:

import cProfile

with cProfile.Profile() as pr:
    # 在這里執(zhí)行代碼
    pr.print_stats()

2. 其他方法

profile.Profile 類還提供了以下方法:

  • create_stats() :停止收集數(shù)據(jù),并將結(jié)果記錄為當前 profile。
  • print_stats(sort=-1) :根據(jù)當前性能分析數(shù)據(jù)創(chuàng)建一個 Stats 對象并打印結(jié)果,sort 參數(shù)用于指定排序方式。
  • dump_stats(filename) :將性能分析結(jié)果寫入指定文件。
  • run(cmd) :對指定命令進行性能分析。
  • runctx(cmd, globals, locals) :在指定的全局和局部環(huán)境下對命令進行性能分析。
  • runcall(func, /, *args, **kwargs) :對函數(shù)調(diào)用進行性能分析。

五、性能分析結(jié)果解讀與應(yīng)用

通過性能分析得到的數(shù)據(jù),我們可以深入理解程序的運行情況,從而進行有針對性的優(yōu)化。

1. 識別性能瓶頸

重點關(guān)注 tottimecumtime 較高的函數(shù),這些函數(shù)可能是程序的性能瓶頸。例如,如果某個函數(shù)的 tottime 很高,說明該函數(shù)自身的執(zhí)行效率較低,可能需要優(yōu)化其算法或?qū)崿F(xiàn)方式;如果 cumtime 較高而 tottime 相對較低,則表明該函數(shù)調(diào)用了許多其他耗時函數(shù),可能需要對整體的函數(shù)調(diào)用結(jié)構(gòu)進行優(yōu)化。

2. 優(yōu)化函數(shù)調(diào)用

根據(jù) ncalls 列,找出調(diào)用次數(shù)過多的函數(shù)。如果一個函數(shù)被頻繁調(diào)用,但其實可以合并或減少調(diào)用次數(shù),那么優(yōu)化這部分代碼將對程序性能產(chǎn)生顯著提升。例如,將一些重復(fù)的計算移到循環(huán)外部,或者使用更高效的數(shù)據(jù)結(jié)構(gòu)來減少不必要的函數(shù)調(diào)用。

3. 分析遞歸函數(shù)

對于遞歸函數(shù),性能分析結(jié)果中的 ncalls 列可能會顯示多個調(diào)用次數(shù)(例如顯示為 3/1),其中第一個數(shù)字是總調(diào)用次數(shù),第二個數(shù)字是原始調(diào)用次數(shù)。通過這種方式,我們可以了解遞歸函數(shù)的調(diào)用深度和頻率,從而判斷是否需要對遞歸實現(xiàn)進行優(yōu)化,或者考慮使用迭代代替遞歸以提高性能。

4. 持續(xù)監(jiān)測與迭代優(yōu)化

性能分析不是一勞永逸的工作,而是一個持續(xù)的過程。在對程序進行優(yōu)化后,再次進行性能分析,對比優(yōu)化前后的數(shù)據(jù),評估優(yōu)化效果。根據(jù)新的分析結(jié)果,繼續(xù)尋找潛在的性能瓶頸并進行優(yōu)化,通過不斷的迭代,逐步提升程序的性能表現(xiàn)。

六、自定義計時器與準確估量

1. 自定義計時器

如果需要改變時間測量方式,可以向 Profile 類構(gòu)造器傳入自定義的計時函數(shù):

import time
pr = profile.Profile(time.perf_counter)
  • 對于 profile.Profile ,計時函數(shù)可以返回一個數(shù)字或數(shù)字列表。
  • 對于 cProfile.Profile ,計時函數(shù)應(yīng)返回一個數(shù)字,如果返回整數(shù),還可以通過第二個參數(shù)指定單位時間長度。

2. 準確估量

為了提高性能分析的準確性,可以對 profile 模塊的性能分析器進行校準:

import profile
pr = profile.Profile()
for i in range(5):
    print(pr.calibrate(10000))

校準后,可以通過以下方式應(yīng)用計算出的偏差值:

# 方法 1:應(yīng)用于所有后續(xù)創(chuàng)建的 Profile 實例
profile.Profile.bias = your_computed_bias

# 方法 2:應(yīng)用于特定的 Profile 實例
pr = profile.Profile()
pr.bias = your_computed_bias

# 方法 3:在構(gòu)造函數(shù)中指定
pr = profile.Profile(bias=your_computed_bias)

七、總結(jié)

掌握 Python 的 cProfileprofile 模塊,能夠讓我們輕松地對程序進行性能分析,找出性能瓶頸并進行優(yōu)化。在編程獅平臺上,您可以進一步學(xué)習(xí)和實踐這些性能分析工具,提升自己的 Python 編程技能,編寫出更高效、更優(yōu)質(zhì)的代碼。通過持續(xù)的性能分析和優(yōu)化,讓您的程序在各種場景下都能表現(xiàn)出色。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號