iOS 底層原理39:Instruments系列(七)Time Profiler

iOS 底層原理 文章匯總

概述

Time Profiler主要用來檢測應(yīng)用CPU的使用情況,可以幫助我們分析代碼/方法的執(zhí)行時(shí)間,找出程序變慢的原因,告訴我們時(shí)間都去哪了

在開發(fā)過程中,點(diǎn)擊按鈕,或者跳轉(zhuǎn)頁面時(shí)有卡頓,即延遲,就可以使用Time Profiler找出耗時(shí)的函數(shù)

原理

Time Profiler是按照固定時(shí)間間隔(1ms)來跟蹤每一個(gè)線程的調(diào)用堆棧信息進(jìn)行采樣,然后通過統(tǒng)計(jì)比較時(shí)間間隔之間的堆棧狀態(tài),來推算某個(gè)方法的執(zhí)行時(shí)間,并獲取一個(gè)近似值。如下所示,圖中虛線是采樣點(diǎn),最后統(tǒng)計(jì)出調(diào)用棧和對應(yīng)函數(shù)調(diào)用的次數(shù)

Instruments_07_01.png

從圖中看出,method3并不在統(tǒng)計(jì)結(jié)果中,這說明只要方法運(yùn)行的足夠快時(shí),是很可能無法統(tǒng)計(jì)到的。對于耗時(shí)分析來說,并不會有什么問題,因?yàn)橹饕欠治鰣?zhí)行慢的方法,執(zhí)行快的方法一般都不會引起性能問題。

而且Time Profiler并不會精確的統(tǒng)計(jì)出方法的執(zhí)行時(shí)間,當(dāng)線程處于掛起或者等待執(zhí)行狀態(tài)時(shí),Time Profiler并不能統(tǒng)計(jì)到此時(shí)的線程,它只能統(tǒng)計(jì)到真正在CPU上執(zhí)行的線程

注意事項(xiàng)

1、必須在iOS真機(jī)上調(diào)試

因?yàn)槟M器是運(yùn)行在Mac上的,然后Mac的CPU一般都比iOS設(shè)備快,兩者的GPU也完全不同,所以如果在模擬器上進(jìn)行調(diào)試,會導(dǎo)致模擬器的性能數(shù)據(jù)和用戶真機(jī)的數(shù)據(jù)相差甚遠(yuǎn)。

2、必須在release環(huán)境下調(diào)試

主要是因?yàn)閄code在debug環(huán)境下會禁用Watch Dog。而在release環(huán)境打包時(shí),編譯器會引入一系列提高性能的優(yōu)化,例如去掉調(diào)試符號、移除并重組代碼等。同時(shí),iOS引入了Watch Dog(看門狗)機(jī)制,在不同的場景下,Watch Dog會監(jiān)測應(yīng)用的性能,如果超出了該場景所規(guī)定的的運(yùn)行時(shí)間,Watch Dog會強(qiáng)制終結(jié)App的進(jìn)程。開發(fā)者可以看到對應(yīng)的crash log。

使用

  • 創(chuàng)建兩個(gè)頁面A和B,從Apush到B,在B的viewDidLoad方法中調(diào)用下面的方法
- (void)testLongTime{
    for (int i = 1; i < 10000000; i ++) {
        NSLog(@"i = %d", i);
    }
}
  • 通過Xcode - Product - Profile - 選擇Time Profiler,配置Call Tree


    Instruments_07_02.png
    • Separate by State:按狀態(tài)分開,分析數(shù)據(jù)。
    • Separate by Thread(建議選擇):線程分離,只有這樣才能在調(diào)用路徑中能夠清晰看到占用CPU最大的線程.每個(gè)線程應(yīng)該分開考慮。只有這樣你才能揪出那些大量占用CPU的"重"線程,按線程分開做分析,這樣更容易揪出那些吃資源的問題線程。特別是對于主線程,它要處理和渲染所有的接口數(shù)據(jù),一旦受到阻塞,程序必然卡頓或停止響應(yīng)。
    • Invert Call Tree(不建議選擇)反向顯示調(diào)用:調(diào)用樹倒返過來,將習(xí)慣性的從根向下一級一級的顯示,如選上就會返過來從最底層調(diào)用向一級一級的顯示。如果想要查看那個(gè)方法調(diào)用為最深時(shí)使用會更方便些。
    • Hide System Libraries(建議選擇)隱藏系統(tǒng)庫:選上它只會展示與應(yīng)用有關(guān)的符號信息,一般情況下我們只關(guān)心自己寫的代碼所需的耗時(shí),而不關(guān)心系統(tǒng)庫的CPU耗時(shí)。
    • Flatten Recursion(一般不選)合并遞歸:選上它會將調(diào)用棧里遞歸函數(shù)作為一個(gè)入口。
    • Top Functions(可選)置頂耗時(shí)方法:選上它會將最耗時(shí)的函數(shù)降序排列,而這種耗時(shí)是累加的,比如A調(diào)用了B,那么A的耗時(shí)數(shù)是會包含B的耗時(shí)數(shù)。
  • 點(diǎn)擊左上角運(yùn)行程序,開啟耗時(shí)檢測,運(yùn)行結(jié)果如下

    Instruments_07_03.png

    從圖中可以看出,大部分時(shí)間占用在-[SecondViewController testLongTime]方法中,雙擊進(jìn)入源代碼頁面,可以具體查看某一行的占用情況
    Instruments_07_04.png

    如果選擇匯編展示
    Instruments_07_05.png

    如果選擇查看次數(shù)
    Instruments_07_06.png

  • 還可以進(jìn)一步設(shè)置耗時(shí)范圍,過濾出想要的數(shù)據(jù),比如設(shè)置最小耗時(shí)為50,過濾50以下的


    Instruments_07_07.png

所以綜上所述,Time Profiler的基本調(diào)試邏輯為

  • 運(yùn)行項(xiàng)目,開始分析
  • 找到最大的占用函數(shù)
  • 修復(fù)耗時(shí)的方法
  • 繼續(xù)分析...直到完全修復(fù)
  • 注:有時(shí)自定義的方法也會引起系統(tǒng)代碼卡頓,所以查看系統(tǒng)庫的耗時(shí)方法也是很有必要的

參考文章

iOS性能優(yōu)化 - 工具Instruments之Time Profiler
iOS 性能優(yōu)化 - TimeProfiler分析代碼耗時(shí)
ios Instruments之Time Profiler
iOS App啟動優(yōu)化(二)—— 使用“Time Profiler”工具監(jiān)控App的啟動耗時(shí)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容