- Tools
- 개발 프로세스마다
- 개발 및 테스팅 -> Xcode(Instrument, Energy Gauger, profiling tools)
- 베타 릴리즈 -> 베타 기기로부터 직접
- 퍼블릭 릴리즈(public release) -> Xcode organizer
- 새로운 Metric 도구 -> 커스텀 정보를 수집할 수 있다!
- XCTest Metrics -> 개발 및 테스팅 단계
- MetricKit -> 베타, 퍼블릭 단계
- 배터리와 성능 관련 지표를 측정하기 위한 프레임워크
- Xcode Metrics Organizer -> 퍼블릭 단계
- 배터리, 성능, I/O지표를 통합해서 보여주는 도구
- Metric이 뭔데? -> 지표
- 배터리 Metric
- processing
- CPU 타임, GPU 타임
- CPU가 너무 많이 돌거나, 의도치 않게 렌더링 되거나 싶을 때
- 알고리즘의 효율성을 비교해보고 싶을 때
- location
- 총 사용시간, 백그라운드 사용 시간
- 필요하지 않은데 켜져 있거나, 필요한 정확도보다 지나치게 높은 정확도를 요구한다던지 하는 경우를 체크
- display
- 평균 픽셀 밝기
- OLED 디스플레이는 컬러에 따라 사용하는 에너지 수준이 다르다.
- networking
- 업로드, 다운로드 바이트, 연결상태 등
- 네트워크 사용을 최적화 하라
- 필요할 때만 업로드, 다운로드가 되는지
- 연결 상태를 점검하라 -> 연결 상태가 안좋으면 통신 시간이 길어져서 효율이 떨어진다.
- accessories(Bluetooth)
- Multimedia
- camera
- 성능 Metric
- Hangs
- 애플리케이션이 사용자 입력을 받지 못한 시간을 나타낸 히스토그램
- UI외의 작업은 최대한 메인 스레드가 아닌 곳에서 실행해야 한다.
- Disk
- 필요할 때만 써지는지
- coaleasing으로 묶어서 되는지
- Application Launch
- Memory
- 평균 suspend 메모리, peak apfhfl
- 메모리 관리는 실행 시간에도 영향을 미친다.
- 재현하기 어려운 메모리 릭, 서스펜드된 메모리를 줄이기 위해 사용
- custom interval
- Deep dives and Demos
- 사용 가능한 툴
- 디버그 네비게이터
- Instrument
- Allocations(메모리 이슈)
- Time profiler(반응성)
- System Usage
- Energy log
- XCTest
- baseline 기반
- iOS 13에 새로운 API 추가
- 테스트 할때는 디버거나 sanitizer 같은 건 다 끄자
- 별도 scheme을 만들어 두면 쉽게 대처 가능하다.
- 커스텀 Metric도 선언 가능하다.
- A/B testing도 가능
- 개발 단계에서 자연스럽게 융합이 가능하다.
func testPhotoUploadPerformance() {
let app = XCUIApplication()
measure(metrics: [XCTClockMetric(),
XCTMemoryMetric(application: app),
XCTCPUMetric(application: app)]) {
app.buttons["Apply Effect"].tap()
app.dialogs["alert"].buttons["OK"].tap()
}
}
func testApplicationLaunchTime() {
measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) {
XCUIApplication().launch()
}
}
- Field Metrics 측정
- MetricKit이라는 새로운 프레임워크 추가
- 일별 MetricReport를 받을 수 있는 Subsciber
- 이때 하루의 여러번 실행했어도 이걸 뭉쳐서 한번에 전달한다.
import MetricKit
class MySubscriber: NSObject, MXMetricManagerSubscriber {
var metricManager: MXMetricManager?
override init() {
super.init()
metricManager = MXMetricManager.shared
metricManager?.add(self)
}
deinit {
metricManager?.remove(self)
}
func didReceive(_ payload: [MXMetricPayload]) {
for metricPayload in payload {
// Metric 데이터 처리
// 여기서 데이터를 파일로 저장하거나 서버로 업로드 하거나 할 수 있다.
}
}
}
// logHandle 만들기
let photosLogHandle: OSLog =
MXMetricManager.makeLogHandle(category: "Photos")
// 실제 코드 사이에 mxSignPost를 넣기
mxSignPost(.begin, log: photosLogHandle, name: "SavePhoto")
savePhoto()
mxSignPost(.end, logL photosLogHandle, name: "SavePhoto")