本章說明如何分析 OCaml 程式的執行效能,藉由記錄函數被呼叫的次數、條件分支被採用的次數等等。
在執行效能分析之前,程式必須使用 ocamlc 編譯器的前端 ocamlcp(參見第 13 章)或 ocamlopt 編譯器的前端 ocamloptp(參見第 16 章),以效能分析模式編譯。當個別編譯模組時,編譯模組(產生 .cmo 或 .cmx 檔案)時必須使用 ocamlcp 或 ocamloptp,並且在連結它們時也可以使用(雖然這不是絕對必要的)。
如果模組(.ml 檔案)沒有對應的介面(.mli 檔案),則使用 ocamlcp 編譯它將產生與 ocamlc 產生的目標檔案(.cmi 和 .cmo)不相容的目標檔案,這可能會在效能分析和非效能分析編譯之間切換時導致問題(如果 .cmi 或 .cmo 仍然存在)。為了避免這個問題,您應該始終為每個 .ml 檔案都有一個 .mli 檔案。ocamloptp 也存在同樣的問題。
為了確保您的程式可以以效能分析模式編譯,請避免使用任何以 __ocaml_prof 開頭的識別符號。
效能分析資訊的數量可以透過 ocamlcp 或 ocamloptp 的 -P 選項控制,後跟一個或多個字母,指示程式的哪些部分應進行效能分析
例如,使用 ocamlcp -P film 編譯會分析函數呼叫、if…then…else…、迴圈和模式匹配。
呼叫 ocamlcp 或 ocamloptp 而不使用 -P 選項預設為 -P fm,這表示只分析函數呼叫和模式匹配。
為了與之前的版本相容,ocamlcp 也接受 -p 選項,其參數和行為與 -P 相同。
ocamlcp 和 ocamloptp 命令也接受相應的 ocamlc 或 ocamlopt 編譯器的所有選項,除了 -pp (預處理) 選項。
執行使用 ocamlcp 或 ocamloptp 編譯的可執行檔會記錄程式指定部分的執行計數,並將其儲存在目前目錄中名為 ocamlprof.dump 的檔案中。
如果在程式退出時設定環境變數 OCAMLPROF_DUMP,則會將其值用作檔案名稱,而不是 ocamlprof.dump。
只有在程式正常終止時(透過呼叫 exit 或自然結束)才會寫入傾印檔案。如果程式因未捕獲的異常而終止,則不會寫入。
如果目前目錄中已存在相容的傾印檔案,則效能分析資訊會累積在此傾印檔案中。這允許例如對程式在不同輸入上的多次執行進行效能分析。請注意,位元組碼可執行檔(使用 ocamlcp 編譯)產生的傾印檔案與原生可執行檔(使用 ocamloptp 編譯)產生的傾印檔案相容。
ocamlprof 命令會產生程式模組的原始碼清單,其中執行計數已作為註解插入。例如,
ocamlprof foo.ml
會印出 foo 模組的原始碼,並加上註解,指示此模組中的函數被呼叫的次數。當然,只有在原始檔在編譯後沒有被修改的情況下,此資訊才是準確的。
ocamlprof 可識別以下選項
使用 ocamlprof 進行效能分析只會記錄執行計數,而不會記錄每個函數內花費的實際時間。目前沒有辦法對 ocamlc 產生的位元組碼程式執行時間效能分析。對於原生程式碼的時間效能分析,建議使用者使用標準工具,例如 perf(在 Linux 上)、Instruments(在 macOS 上)和 DTrace。不再支援使用 gprof 進行效能分析。