硬廣:《IOS性能調優系列》第五篇,預計會有二十多篇,持續更新,歡迎關注。
之前四篇都是關注於內存方面,分析了內存洩漏、僵屍對象、內存分配,本篇介紹Time Profiler工具的使用,開始真正的“性能”調優之旅。
Time Profiler還有之前介紹過的Leaks、Allocations工具,被戲稱為Instruments的救命三招,是當應用遇到問題時首先應當使用的三個工具。
Time Profiler幫助我們分析代碼的執行時間,找出導致程序變慢的原因,告訴我們“時間都去哪兒了?”。
在使用Time Profiler之前,先看看原始的性能分析方法。
原始的性能分析方法
這種分析方法估計是很多開發人員第一時間想到的,寫個單元測試,在開始和結束的地方記錄時間。
示例代碼:
NSDate *stDate = [NSDate date]; for(int i = 0; i < 999; i++) { // do something } NSDate *endDate = [NSDate date]; NSLog(@"time:%f", [endDate timeIntervalSinceDate:stDate]);
通過計算時差,可以算出中間消耗的時間,通過這種辦法可以一部分一部分的對可能出現性能瓶頸的代碼進行分析。
這種方法的缺點有以下亮點:
1、測試效率太低,很多性能瓶頸是很難預估到的,需要從上層到下層進行逐步排除;
2、無法對界面渲染的效率進行測試,找出界面性能瓶頸;
3、NSLog的分析不夠精確,可能在模擬器上由於開發設備性能速度快,無法明顯區分出性能瓶頸。
這也是使用Time Profiler工具的優勢,能以極高的效率找出性能瓶頸。
使用Time Profiler的性能分析方法
Time Profiler分析原理:它按照固定的時間間隔來跟蹤每一個線程的堆棧信息,通過統計比較時間間隔之間的堆棧狀態,來推算某個方法執行了多久,並獲得一個近似值。其實從根本上來說與我們的原始分析方法異曲同工,只不過其將各個方法消耗的時間統計起來。
和使用 Instruments的其他工具一樣,點擊XCode的Product菜單Profile啟動Instruments:
選擇Time Profiler工具開始測試,這時會自動啟動模擬器和Time Profiler錄制。
先進行一些App的操作,讓Time Profiler收集足夠的數據,尤其是你覺得那些有性能瓶頸的地方。
4、5、6所標記的面板是需要關注的:
4是擴展面板,用來跟蹤顯示堆棧;5是詳細地面板,可以從這裡看到cpu運行的時間都消耗在哪裡;6是選項面板,可以用來設置Time Profiler的運行參數。
通過對應用的操作,可以在詳細面板中看到那些最耗時的操作是哪些,並可以逐行展開查看:
圖標為黑色頭像的就是Time Profiler給我們的提示,有可能存在性能瓶頸的地方,可以逐漸向下展開,找到產生的根本原因。
比如我們通過分析,發現[CMTool getNewsTimeFromLong]這個時間格式化函數可能需要優化。
當然這裡只是舉一個例子,性能調優應該首先從整體到細節的順序進行,才能收到最明顯的效果。
Time Profiler參數設置
這裡邊幾個選項的含義如下:
Separate by Thread: 每個線程應該分開考慮。只有這樣你才能揪出那些大量占用CPU的"重"線程
Invert Call Tree: 從上倒下跟蹤堆棧,這意味著你看到的表中的方法,將已從第0幀開始取樣,這通常你是想要的,只有這樣你才能看到CPU中話費時間最深的方法.也就是說FuncA{FunB{FunC}} 勾選此項後堆棧以C->B-A 把調用層級最深的C顯示在最外面
Hide Missing Symbols: 如果dSYM無法找到你的app或者系統框架的話,那麼表中看不到方法名只能看到十六進制的數值,如果勾線此項可以隱藏這些符號,便於簡化數據
Hide System Libraries: 勾選此項你會顯示你app的代碼,這是非常有用的. 因為通常你只關心cpu花在自己代碼上的時間不是系統上的
Show Obj-C Only: 只顯示oc代碼 ,如果你的程序是像OpenGl這樣的程序,不要勾選側向因為他有可能是C++的
Flatten Recursion: 遞歸函數, 每個堆棧跟蹤一個條目
Top Functions: 一個函數花費的時間直接在該函數中的總和,以及在函數調用該函數所花費的時間的總時間。因此,如果函數A調用B,那麼A的時間報告在A花費的時間加上B花費的時間,這非常真有用,因為它可以讓你每次下到調用堆棧時挑最大的時間數字,歸零在你最耗時的方法。
上面的參數在實踐中合理設置,也沒有什麼太多技巧,就是通過數據的隱藏、顯示讓我們更關注於想找到的數據。
天下應用,唯快不破!尤其是手機應用,更應該注意用戶體驗和響應速度。