檢視原始碼 cprof (工具 v4.1.1)
一個使用斷點的簡單呼叫計數分析工具,將執行時期效能影響降至最低。
cprof
模組用於分析程式,以找出不同函式被呼叫的次數。為了將執行時期效能影響降至最低,使用了包含計數器的斷點。
由於使用了斷點,因此不需要對要分析的模組進行特殊編譯。這些斷點只能設定在 BEAM 程式碼上,因此無法追蹤 BIF 的呼叫計數。
呼叫計數器的大小為主機的字組大小。當暫停計數器時,會使用一個位元,因此 32 位元主機的最大計數器值為 2,147,483,647。
分析結果會以一個包含排序過的條目清單的 term 形式傳遞,每個模組一個條目。每個模組條目都包含一個排序過的函式清單。在這兩種情況下,排序順序都是依呼叫計數遞減。
與其他形式的追蹤(例如 eprof
或 fprof
)相比,呼叫計數追蹤是輕量級的,因為不需要產生追蹤訊息。一些測量結果表明,效能下降約 10%。
如需更多資訊和一些範例,請參閱 cprof
的使用者指南。
摘要
函式
等同於 analyse(1)
。
為一個或多個模組收集呼叫計數器。
收集並分析模組 Module
的所有呼叫計數器。
暫停所有模組中所有函式的呼叫計數追蹤,並停止追蹤要載入的模組中的所有函式。
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 pause(FuncSpec, '_', '_')
。
暫停匹配模組中匹配函式的呼叫計數器。
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 restart(FuncSpec, '_', '_')
。
重新啟動正在追蹤呼叫計數的匹配模組中匹配函式的呼叫計數器。
開始追蹤所有模組中所有函式的呼叫計數,以及要載入的模組中的所有函式。
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 start(FuncSpec, '_', '_')
。
開始追蹤匹配模組中匹配函式的呼叫計數。
停止追蹤所有模組中所有函式的呼叫計數,以及要載入的模組中的所有函式。
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 stop(FuncSpec, '_', '_')
。
停止追蹤匹配模組中匹配函式的呼叫計數。
類型
-type func_analysis_list() :: [{mfa(), FuncCallCount :: non_neg_integer()}].
-type mod_analysis() :: {Mod :: module(), ModCallCount :: non_neg_integer(), FuncAnalysisList :: func_analysis_list()}.
-type mod_analysis_list() :: [mod_analysis()].
函式
-spec analyse() -> {AllCallCount :: non_neg_integer(), ModAnalysisList :: mod_analysis_list()}.
等同於 analyse(1)
。
-spec analyse(Limit) -> {AllCallCount :: non_neg_integer(), ModAnalysisList :: mod_analysis_list()} when Limit :: non_neg_integer(); (Mod) -> ModAnalysis :: mod_analysis() when Mod :: module().
為一個或多個模組收集呼叫計數器。
如果 ModLimit
是一個模組名稱(一個 atom),則此呼叫等同於 analyse(ModLimit, 1)
。
如果 ModLimit
是一個整數,則此函式會針對目前已載入的每個 Module
(除了 cprof
模組本身)呼叫 analyse(Module, ModLimit)
。這些呼叫的結果會在清單中傳回。
-spec analyse(Mod, Limit) -> ModAnalysis :: mod_analysis() when Mod :: module(), Limit :: non_neg_integer().
收集並分析模組 Module
的所有呼叫計數器。
此函式傳回
{Module, ModuleCount, FuncAnalysisList}
其中 FuncAnalysisList
是一個 tuple 清單,每個函式一個 tuple
{{Module, FunctionName, Arity}, FuncCallCount}
如果在執行 analyse/0,1,2
時呼叫計數器仍在執行,則結果可能不一致。如果執行 analyse/0,1,2
的程序被排程出去,讓其他程序可以遞增正在分析的計數器,就會發生這種情況。在分析之前呼叫 pause()
可以解決這個問題。
所有 FuncCallCount
低於 Limit
的函式都會從 FuncAnalysisList
中排除。但是,它們仍然會包含在 ModCallCount
中。
-spec pause() -> non_neg_integer().
暫停所有模組中所有函式的呼叫計數追蹤,並停止追蹤要載入的模組中的所有函式。
-spec pause(FuncSpec) -> non_neg_integer() when FuncSpec :: (Mod :: module()) | mfa() | {FS :: term()}.
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 pause(FuncSpec, '_', '_')
。
如果 FuncSpec
是一個 MFA tuple,{Module, Name, Arity
},則此呼叫等同於 pause(Module, Name, Arity)
。
如果 FuncSpec
是一個 tuple {FS}
,則 FS
是 erlang:trace_pattern/3
的第一個引數。例如,如果 FuncSpec
是 {on_load}
,則將暫停追蹤要載入之模組中所有函式的呼叫計數器。
-spec pause(Mod, Func) -> non_neg_integer() when Mod :: module(), Func :: atom().
-spec pause(Mod, Func, Arity) -> non_neg_integer() when Mod :: module(), Func :: atom(), Arity :: arity().
暫停匹配模組中匹配函式的呼叫計數器。
所有具有呼叫計數斷點的匹配函式的呼叫計數器都會在目前的計數暫停。
傳回可以具有呼叫計數斷點的匹配函式數量,與使用相同引數的 start/*
將會傳回的數量相同。
-spec restart() -> non_neg_integer().
-spec restart(FuncSpec) -> non_neg_integer() when FuncSpec :: (Mod :: module()) | mfa() | {FS :: term()}.
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 restart(FuncSpec, '_', '_')
。
如果 FuncSpec
是一個 MFA tuple,{Module, Name, Arity
},則此呼叫等同於 restart(Module, Name, Arity)
。
如果 FuncSpec
是一個 tuple {FS}
,則 FS
是 erlang:trace_pattern/3
的第一個引數。例如,如果 FuncSpec
是 {on_load}
,則會將要載入之模組中所有函式的呼叫計數器設定為零並開始執行。
-spec restart(Mod, Func) -> non_neg_integer() when Mod :: module(), Func :: atom().
-spec restart(Mod, Func, Arity) -> non_neg_integer() when Mod :: module(), Func :: atom(), Arity :: arity().
重新啟動正在追蹤呼叫計數的匹配模組中匹配函式的呼叫計數器。
會將所有具有呼叫計數斷點的匹配函式的呼叫計數器設定為零並開始執行。
傳回可以具有呼叫計數斷點的匹配函式數量,與使用相同引數的 start/*
將會傳回的數量相同。
-spec start() -> non_neg_integer().
開始追蹤所有模組中所有函式的呼叫計數,以及要載入的模組中的所有函式。
-spec start(FuncSpec) -> non_neg_integer() when FuncSpec :: (Mod :: module()) | mfa() | {FS :: term()}.
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 start(FuncSpec, '_', '_')
。
如果 FuncSpec
是一個 MFA tuple,{Module, Name, Arity
},則此呼叫等同於 start(Module, Name, Arity)
。
如果 FuncSpec
是一個 tuple {FS}
,則 FS
是 erlang:trace_pattern/3
的第一個引數。例如,如果 FuncSpec
是 {on_load}
,則會將要載入之模組中所有函式的呼叫計數器設定為零並開始執行。
-spec start(Mod, Func) -> non_neg_integer() when Mod :: module(), Func :: atom().
-spec start(Mod, Func, Arity) -> non_neg_integer() when Mod :: module(), Func :: atom(), Arity :: arity().
開始追蹤匹配模組中匹配函式的呼叫計數。
在沒有呼叫計數斷點的匹配函式上設定呼叫計數斷點。會將所有匹配函式的呼叫計數器設定為零並開始執行。
傳回具有呼叫計數斷點的匹配函式數量。
-spec stop() -> non_neg_integer().
停止追蹤所有模組中所有函式的呼叫計數,以及要載入的模組中的所有函式。
-spec stop(FuncSpec) -> non_neg_integer() when FuncSpec :: (Mod :: module()) | mfa() | {FS :: term()}.
如果 FuncSpec
是一個 atom,則假定它是一個模組名稱,並且此呼叫等同於 stop(FuncSpec, '_', '_')
。
如果 FuncSpec
是一個 MFA tuple,{Module, Name, Arity
},則此呼叫等同於 stop(Module, Name, Arity)
。
如果 FuncSpec
是一個 tuple {FS}
,則 FS
是 erlang:trace_pattern/3
的第一個引數。例如,如果 FuncSpec
是 {on_load}
,則會停用要載入之模組中所有函式的呼叫計數器。
-spec stop(Mod, Func) -> non_neg_integer() when Mod :: module(), Func :: atom().
等同於 stop(Mod, Func, '_')
。
-spec stop(Mod, Func, Arity) -> non_neg_integer() when Mod :: module(), Func :: atom(), Arity :: arity().
停止追蹤匹配模組中匹配函式的呼叫計數。
從具有呼叫計數斷點的匹配函式中移除呼叫計數斷點。
傳回可以具有呼叫計數斷點的匹配函式數量,與使用相同引數的 start/*
將會傳回的數量相同。