摘要
近期对接客户时,客户方希望提供 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 中要公示给用的隐私相关。这两部分都要给到应该对接方,以免因为缺少必要的隐私设置,影响到应用上线审核。