圖 1 -1 Profiler 入口
要分析獨立應用程序 需要勾選以下量兩項,否則不精准
圖 1- 2 啟動標志
打開Profiler ,
圖 1-3 Profiler 界面常規設置
PlayModel :運行模式下 我們就用這個
Hierarchy: 表示瀏覽視圖 選擇這個 便於觀察
DeepProfiler:表示深層次探測,選中此選項 會重新編譯項目,而且堆棧信息比較全面,層次太深,不方便查看。一般不需要選中。
我們經常聽說幀率:每秒 30Fps ,45FPS , 60FPS ,那么每幀的時間是多少? 1秒是1000ms,每幀的時間 = 1000 / 幀率 。如果游戲設定是30FPS ,那每幀的時間是 1000 / 30 = 33.3ms ,也就是說 留給CPU 每幀計算的時間只有 33.3ms.
可以通過API 強制設置幀率:Application.targetFrameRate = 30 ,設置-1為不限制幀率,同時 我們要關閉掉 垂直同步Vsync。垂直同步:應用程序的幀率會受監視器的幀率限制。
圖 1- 4 關閉垂直同步
運行游戲 ,點擊游戲中的球員管理,里面是有2000多張卡牌的 需要計算戰力的,比較耗時。
圖 1-5 打開球員管理界面 有一個瞬間高峰
用鼠標選中高峰,查看此時的 GC及相應的耗時
圖1- 6 打開球員管理 標記耗時操作
GetPower 耗時 31.78毫秒,其中 GetPower0 25.22毫秒
那么這些BaseCardModel xxx =====>>> 是怎么來的呢? 使我們在代碼中寫的,便於識別:
圖 1-7 代碼采樣
代碼中BeginSample 一層套一層,在Profiler窗口中也是如此展示,為了便於得知每一層的耗時是多少。
圖 1-8 不同層次的耗時
打開發現 GetPower0 里面還有2層 , 這是因為:我們調用了GetCardAbilityAllPower() 方法
這里也是為了 弄清楚 耗時出現在一塊,便於我們去優化。
LuaProfilerUtl 的代碼 僅對 Profiler采樣進行簡單的封裝,會了更加便於獲知 耗時。代碼如下:

1 local LuaProfilerUtl = {} 2 local _isOpen = Application.isEditor == true or is_show_profiler_log == true
3 local __profilerMap = {} 4
5 local function _getkey(...) 6 local par = { ... } 7 local key = ""
8 for _, value in pairs(par) do
9 if key == "" then
10 key = tostring(value) 11 else
12 key = key .."_"..tostring(value) 13 end
14 end
15 end
16
17 function LuaProfilerUtl.Begin(...) 18 if _isOpen == false then return end
19 local key = _getkey(...) 20 __profilerMap[key] = Time.realtimeSinceStartup 21 end
22
23
24 function LuaProfilerUtl.End(...) 25 if _isOpen == false then return end
26 local key = _getkey(...) 27 if type(__profilerMap[key]) ~= "number" then return end
28 if is_show_profiler_log then
29 print(key.. "======>" .. string.format("%.4f", Time.realtimeSinceStartup - __profilerMap[key] )) 30 else
31 print(key.. "======>" .. string.format("%.4f", Time.realtimeSinceStartup - __profilerMap[key] )) 32 end
33 end
34
35 function LuaProfilerUtl.BeginSample(...) 36 if _isOpen == false then return end
37 local key = _getkey(...) 38 Profiler.BeginSample(key) 39 end
40
41 function LuaProfilerUtl.EndSample(params) 42 if _isOpen == false then return end
43 Profiler.EndSample() 44 end
45
46 return LuaProfilerUtl
繼前面說的FPS,我們切換到Timeline 視圖,如圖 1-5 ,高峰耗時達到73.87ms , 1000 / 73.87ms = 13.5FPS 。數據太多,cpu計算耗時,界面打開一瞬間FPS降低。 GPU 在未收到CPU的數據期間一直處於等待狀態。
圖1-9Timeline 視圖
Gfx.WaitForGfxCommandsFormMainThread:GPU正在等待CPU完成計算,GPU處於空閑階段。
由此我們可以得出:性能瓶頸是卡在CPU 還是GPU ,便於我們進一步的精准優化。