一: Time Profiler
Time Profiler用來分析代碼的執(zhí)行時間,主要用來分析CPU使用情況。
注意:要在release模式(或者自定義的其他的打包模式)下分析,原因在release模式下:
- 會開啟編譯器優(yōu)化,提高代碼運行效率
- 生成調(diào)試的符號表,這樣才能夠在profile的時候看到代碼的調(diào)用棧
- 多數(shù)條件編譯只會在debug模式下生效桑驱,release模式和生產(chǎn)環(huán)境是一樣的。
二: 原理
Time Profiler每隔1ms會對線程的調(diào)用棧采樣跛蛋,然后用統(tǒng)計學(xué)的方式去做出分析熬的。
圖中虛線是采樣點,最后統(tǒng)計出調(diào)用棧和對應(yīng)函數(shù)出現(xiàn)的個數(shù)赊级。
從圖中不難看出押框,method3
并沒有出現(xiàn)在統(tǒng)計結(jié)果中,也就意味著方法運行的足夠快的時候理逊,很有可能統(tǒng)計不到橡伞,但這對于分析來說并不會有太大影響,因為運行快的方法往往不會引起性能問題挡鞍。
Tips:Time Profiler并不會精確的統(tǒng)計出方法的執(zhí)行時間,當(dāng)線程處于掛起和等待執(zhí)行的狀態(tài)時候预烙,timer profiler并不能統(tǒng)計到墨微,它只能統(tǒng)計到真正在CPU上執(zhí)行的。
三: Demo
Demo工程是一個簡易的相冊應(yīng)用扁掸,故意寫的很爛翘县,包含了三個界面:
? 第一個界面只提供一個入口
? main界面用瀑布流的方式提供圖片預(yù)覽,圖片被加了濾鏡
? detail界面可以查看大圖
在iPhone 6上運行谴分,在進入main界面的時候會看到明顯的卡頓:
我們通過Time Profile來找到原因:Product -> Profile
這會讓XCode執(zhí)行一次Release的build锈麸,然后啟動Instrument
我們選擇Time Profiler啟動,然后正常操作App牺蹄,采集到了數(shù)據(jù)后忘伞,停止Instrument。
對圖中的幾點說明:
- 各個線程的采集數(shù)據(jù)匯總
- 點擊1中的某一行,可以看到采集到的堆棧氓奈,注意2區(qū)域的右上角翘魄,可以選擇隱藏系統(tǒng)的符號
- 可以選擇關(guān)注的隊列/CPU等。
- 可以用pinch手勢來放大縮小時間范圍舀奶,鼠標(biāo)可以拖動選擇一段區(qū)域
Tips:
Weight表示占用全部的百分比
Self Wight表示當(dāng)前方法執(zhí)行占用的百分比暑竟,如果看到是0,表示當(dāng)前方法其實不占用什么時間育勺,時間都是子程序調(diào)用占用的但荤。
我們用鼠標(biāo)拖動,選擇選擇CPU占用較高的部分涧至,可以看到堆棧如下:
Tips: 按住Option腹躁,然后鼠標(biāo)左鍵點圖中的箭頭,可以快速展開化借。
從圖中看到:大部分時間占用在-[MainController loadAllImages]
這個方法:讀取本地圖片潜慎,然后對圖加濾鏡
- (void)loadAllImages{
NSMutableArray * images = [NSMutableArray new];
for (long i = 1; i < 40; i++) {
NSString * imageName = [NSString stringWithFormat:@"image_%ld",i % 20 + 1];
NSString * imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"jpeg"];
UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
[images addObject:[self filterdImage:image]];
}
self.images = [images copy];
}
我們可以勾選以下選項,來看得更清楚一些:
- Hide System Libraries 隱藏系統(tǒng)的庫
- Invert Call Tree 倒置函數(shù)隊?wèi)?zhàn)
勾選后
Timer Profiler的基本debug邏輯:分析 -> 找到最大的占用函數(shù) -> 修復(fù) -> 繼續(xù)分析…蓖康,直到完全修復(fù)铐炫。有時候自己的代碼會引起系統(tǒng)代碼卡頓,所以查看系統(tǒng)庫的卡頓也很有必要的蒜焊。
可以通過雙擊一行倒信,進入源代碼界面,看看具體某一行的占用情況:
也可以選擇查看次數(shù):
查看次數(shù):
或者泳梆,查看反匯編
四: FAQ
為什么我在Time Profiler看不到類和方法的名稱呢鳖悠?
絕大部分原因是你的打包模式?jīng)]有開啟dSYM
或者debug symbols
為什么明明我的App很卡,可是用Time Profiler分析卻找不到相關(guān)代碼优妙?
卡頓的原因主要分為兩大類:CPU瓶頸和GPU瓶頸
當(dāng)界面有大量的shadow乘综,mask或者有非常多的View/Layer,GPU渲染紋理和頂點的時候可能會有壓力套硼,這時候應(yīng)該用Core Animation觀察GPU的使用率卡辰。
CPU引起的卡頓大多可以通過Time Profiler
找到,如果找不到可能的原因有兩個:
- 代碼引起了大量系統(tǒng)調(diào)用邪意,占用CPU時間九妈,這種情況你需要仔細(xì)分析Time Profiler中的系統(tǒng)占用。
- 頻繁的鎖和線程切換雾鬼。因為線程被掛起的時候萌朱,time profiler無法采樣到,這種情況可以通過System Trace分析策菜。