簡體   English   中英

Python中的分析:誰調用了函數?

[英]Profiling in Python: Who called the function?

我正在使用cProfile在Python中進行cProfile 我發現一個占用大量CPU時間的函數。 我如何找出哪個函數調用這個重函數最多?

編輯:

我會解決一個解決方法:我可以在那個重函數中編寫一個Python行,它將打印調用它的函數的名稱嗎?

我幾乎總是使用Gprof2dot查看cProfile模塊的輸出,基本上它將輸出轉換為graphvis圖( .dot文件),例如:

示例gprof2dot輸出

它可以很容易地確定哪個函數最慢,哪個函數調用它。

用法是:

python -m cProfile -o output.pstats path/to/your/script arg1 arg2
gprof2dot.py -f pstats output.pstats | dot -Tpng -o output.png

這可能不會直接回答你的問題,但肯定會有所幫助。 如果使用帶有選項--sort cumulative的探查器,它將按累計時間對函數進行排序。 這不僅有助於檢測繁重的功能,還可以檢測調用它們的功能。

python -m cProfile --sort cumulative myScript.py

有一個解決方法來獲取調用函數:

import inspect
print inspect.getframeinfo(inspect.currentframe().f_back)[2]

您可以根據需要添加任意數量的f_back,以防您需要調用者調用者等。如果您想計算頻繁調用,可以執行以下操作:

record = {}

caller = inspect.getframeinfo(inspect.currentframe().f_back)[2]
record[caller] = record.get(caller, 0) + 1

然后按頻率順序打印:

print sorted(record.items(), key=lambda a: a[1])

inspect.stack()將為您提供當前的調用者堆棧。

你可能想看一下pycallgraph

可以使用標准庫中的profiler cProfile來完成它。
pstats.Stats (探查器結果)中有方法print_callees (或者print_callers )。


示例代碼:

import cProfile, pstats
pr = cProfile.Profile()
pr.enable()

# ... do something ...

pr.disable()
ps = pstats.Stats(pr).strip_dirs().sort_stats('cumulative')
ps.print_callees()

結果將是這樣的:

Function                           called...
                                       ncalls  tottime  cumtime
ElementTree.py:1517(_start_list)   ->   24093    0.048    0.124  ElementTree.py:1399(start)
                                        46429    0.015    0.041  ElementTree.py:1490(_fixtext)
                                        70522    0.015    0.015  ElementTree.py:1497(_fixname)
ElementTree.py:1527(_data)         ->   47827    0.017    0.026  ElementTree.py:1388(data)
                                        47827    0.018    0.053  ElementTree.py:1490(_fixtext)

左邊是調用者,右邊是被調用者。
(例如_fixtext被稱為從_data 47827倍,並從_start_list 46429倍)


也可以看看:


幾個筆記:

  • 您需要為此編輯代碼(插入這些配置文件語句)。
    (即不能在命令行中使用,如python -m cProfile myscript.py 。雖然可以為此編寫單獨的腳本)
  • 有點不相關,但strip_dirs()必須在sort_stats()之前(否則排序不起作用)

我自己沒有使用過cProfile,但是大多數分析器都會給你一個調用層次結構。
谷歌搜索我發現這個幻燈片關於cProfile。 也許這有幫助。 看起來cProfile確實提供了層次結構。

Pycscope做到了這一點。 我今天剛剛發現它,所以我不能說它有多好,但我嘗試過的幾個例子都非常好(雖然並不完美)。

https://pypi.python.org/pypi/pycscope/

您可以使用它來生成cscope文件,然后從編輯器(特別是VIM)生成cscope插件。 我嘗試使用它與vanilla cscope,似乎普通的cscope感到困惑。

對不起,我不熟悉Python,但有一個通用的方法可行,假設您可以隨機手動中斷執行。

只需這樣做,並顯示調用堆棧。 它會很有可能告訴你你想知道什么。 如果你想更加確定,只需要做幾次。

它的工作原理是因為有罪的調用者必須在調用堆棧中浪費一小部分時間,這會在很長一段時間內將其暴露給你的中斷,無論是分散在很多短暫的調用還是一些冗長的調用。

注意:此過程更像是診斷而非測量。 假設糟糕的通話浪費了90%的時間。 然后,每次你停止它時,錯誤的調用語句就在調用堆棧上的概率是90%,你可以看到,這將是壞的。 但是,如果你想准確衡量浪費,那就是另一個問題。 為此,您需要更多樣本,以查看它們中包含該調用的百分比。 或者,只需修復有罪的電話,計算加速時間,這將告訴你究竟什么是浪費。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM