摘要
近期對接客戶時,客戶方希望提供 SDK 的性能、內存、隱私支持等一些數據,所以就對 SDK 進行了一些性能測試。
在用表格統計整理這些數據時,突然發現,經常用統計的方式看 SDK 的相關數據,似乎也是一個發現優化的好方式。
所以想記錄下來統計表格式、測試工具等,方便后面去優化 SDK。
SDK 數據表格
首先把 SDK 中性能、內存有關的數據給整理一下,我這邊做成如下圖的表格,方便統計和查看。
接下來,按照表格中的各個項目,去獲取。
性能數據
CPU 消耗和內存消耗,這兩個數據可以直接通過 Xcode 中獲取到。把程序運行起來后,按照下圖切換到這個面板,就可以查看到 CPU 消耗和內存消耗的實時數值。這里獲取到分別是它們的最大值。
CPU 消耗
這里比較有意思的數據是 CPU。看到 CPU 的刻度能到 600%,為什么這么大?
因為我這是用的手機是 iphone 12Pro,它有 6 CPU,所以它的 CPU 最高就是 6 個 CPU滿載運行,即 600%。所以獲取到的值需要除以 6 才是真正的 CPU 消耗占比。
這里用到不同設備獲取 CPU,在上圖的面板中都會獲取到不同的數值,所以,不可以拿面板中的值直接去放在其他設備上計算獲得,比如不能直接除以 2 獲取到 iphone 7 的 CPU 消耗占比。
內存消耗
內存消耗,是整體跑完 SDK 的功能之后,獲取到內存消耗的最大值。這里在統計數據時要記得減去初始內存消耗,也就是不運行 SDK 中的功能時的內存消耗。
因為在 APP 啟動完成時,也會需要內存消耗,這部分的內存消耗是維持 APP 正常運行,使用 SDK 的功能時,就會在這個基礎上去增加它的內存消耗。
FPS(每秒傳輸幀數-Frames Per Second)
FPS 是圖像領域中的定義,是指畫面每秒傳輸幀數,每秒幀數越多,所顯示的動作就會越流暢。通常,要避免動作不流程的最低是 30。
FPS 也可以理解為常說的“刷新率(單位為 Hz)‘,比如,75 Hz 的刷新率指屏幕一秒內只掃描 75 次,即 75 幀/秒。
監測 FPS
蘋果提供 CADisplayLink 類監測 FPS。CADisplayLink 可以創建一個計時對象,允許應用程序將繪圖與顯示的刷新率同步。
下面是相關的代碼:
import UIKit
class FPSLabel: UILabel {
private var link:CADisplayLink?
private var lastTime:TimeInterval = 0.0;
private var count:Int = 0;
override init(frame: CGRect) {
super.init(frame: frame)
//receiver是指didTick方法
link = CADisplayLink.init(target: self, selector: #selector(FPSLabel.didTick(link:)))
//commom會無論用戶的app處於什么停止還是滑動都會進行fps打印(commonMode會添加timer到所有mode上面)
link?.add(to: RunLoop.current, forMode: .common)
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
@objc func didTick(link:CADisplayLink) {
if lastTime == 0 {
lastTime = link.timestamp
return
}
//用來記錄一秒進入這個方法多少次,如果進入了20次那么count就變成20,20幀
count += 1
//在一秒內打印的次數
let delta = link.timestamp - lastTime
if delta < 1{
//不夠一秒就返回,繼續往上面count加一,這樣就可以獲得一秒內有多少個頁面
return
}
//這時候已經到一秒了,我們先把lastTime更新至當前時間以便下一次計算
lastTime = link.timestamp
//delta是1.0000000....
print("delta :\(delta)")
let fps = Double(count)/delta
count = 0
text = String.init(format: "%02.0f幀", round(fps))
print(text ?? "0")
}
}
兼容
兼容項就很容易獲取到,首先是 SDK 可以運行的最低系統版本,這個在項目工程中就可以設置,也可以輕松獲取到。另外一個是設備,這個范圍就比較廣,移動設備、iPad、iWatch 還是其他設備,這個根據項目來處理。
加載時間
這里使用比較的方法來獲取加載時間,即先跑一下沒有 Framework 的加載時間,然后再跑一下有 Framework 的加載時間,做個差值就出來了(方法比較簡單)。
在項目里面,選擇 Edit Scheme..
選項,然后在 Run
選項中設置 DYLD_PRINT_STATISTICS
為 1。
之后,每次運行項目的時候都會在打印的工作台中顯示這些數據:
Total pre-main time: 242.05 milliseconds (100.0%)
dylib loading time: 151.75 milliseconds (62.6%)
rebase/binding time: 22.21 milliseconds (9.1%)
ObjC setup time: 6.99 milliseconds (2.8%)
initializer time: 61.09 milliseconds (25.2%)
slowest intializers :
libSystem.B.dylib : 7.70 milliseconds (3.1%)
libBacktraceRecording.dylib : 8.65 milliseconds (3.5%)
libMainThreadChecker.dylib : 40.24 milliseconds (16.6%)
計算的時候,只需要看第一項的時間就好,其他選項有別的用處,這里不做深入的探討。
安裝包大小
安裝包大小參考的值可以在 appStore 發布平台上查看。主要看安裝大小這個指標就可以。安裝大小就是應用安裝到設備中用到的內存大小。
這里獲取 Framework 安裝大小是先上傳一個空應用,然后再上傳一個有 Framework 的應用,前后比較得到 Framwork 包的安裝大小。不要通過查看 .ipa 包文件這些看似直接快速的手段,數據非常的不真實,沒有實際的參考意義。
隱私權限
隱私權限部分分為兩個部分,一個是在 SDK 中要使用到的設備權限,比如需要使用攝像頭拍照權限,那么在項目中就要設置獲取權限。另外一個是要在 App Store 中要公示給用的隱私相關。這兩部分都要給到應該對接方,以免因為缺少必要的隱私設置,影響到應用上線審核。