Instruments — เป็นโปรไฟล์เลอร์ที่ติดตั้งใน Xcode สำหรับวิเคราะห์ประสิทธิภาพของแอปพลิเคชัน iOS, macOS, tvOS และ watchOS เครื่องมือนี้มีชุดเทมเพลตสำหรับวัด CPU, หน่วยความจำ, เครือข่าย, กราฟิก และการใช้พลังงานแบบเรียลไทม์ ตาม Apple Developer Documentation แล้ว Instruments ถูกใช้ในทุกขั้นตอนของการพัฒนา — ตั้งแต่การค้นหารั่วไหลไปจนถึงการปรับปรุงเวลาเริ่มต้นแอปพลิเคชัน
ประเด็นสำคัญ
Instruments — เป็นระบบการโปรไฟล์และติดตามที่เป็นส่วนหนึ่งของ Xcode และมีพื้นฐานมาจากเทคโนโลยี DTrace ที่พัฒนาโดย Sun Microsystems Instruments รวมเครื่องมือโปรไฟล์หลายสิบชิ้น (เทมเพลต) ไว้ในอินเทอร์เฟซเดียว: เพียงเลือกเทมเพลต เริ่มแอปพลิเคชันผ่าน Xcode และเริ่มเก็บข้อมูล
สถาปัตยกรรมของ Instruments สร้างขึ้นบนโมเดลไคลเอนต์-เซิร์ฟเวอร์: เอเจนต์บนอุปกรณ์เก็บข้อมูลและส่งไปยัง Mac ผ่านการเชื่อมต่อ USB ซึ่งช่วยลดผลกระทบของโปรไฟล์เลอร์ต่อประสิทธิภาพของแอปพลิเคชัน — Instruments ทำงานหลักบนฝั่งโฮสต์ ตาม WWDC 2022 แล้ว โอเวอร์เฮดของ Time Profiler ที่อัตราการสุ่มตัวอย่าง 1 ms น้อยกว่า 3%
Instruments รองรับ เทมเพลตที่กำหนดเอง — นักพัฒนาสามารถรวมเครื่องมือหลายชิ้นในเซสชันการโปรไฟล์เดียว ตัวอย่างเช่น เริ่ม Time Profiler + Allocations + Leaks พร้อมกันและดูความสัมพันธ์ระหว่างจุดสูงสุดของ CPU และการจัดสรรหน่วยความจำ ซึ่งให้ภาพรวมประสิทธิภาพที่ไม่สามารถหาได้จากการวิเคราะห์แต่ละส่วนประกอบแยกกัน
Xcode มาพร้อมกับเทมเพลต Instruments ที่ติดตั้งไว้ล่วงหน้า 16 รายการ: Time Profiler, Allocations, Leaks, Energy Log, Network, Core Animation, Metal System Trace, File Activity, System Trace และอื่นๆ แต่ละเทมเพลตถูกปรับให้เหมาะสมสำหรับงานเฉพาะและได้รับการกำหนดค่าล่วงหน้าด้วยการตั้งค่าทริกเกอร์และตัวกรองที่ถูกต้อง
Time Profiler — เป็นเทมเพลต Instruments ที่ใช้มากที่สุด มันทำงานบนพื้นฐานการสุ่มตัวอย่างสแต็กเรียก: ทุก 1-10 มิลลิวินาที ระบบจะบันทึกสแต็กเรียกของทุกเธรดของแอปพลิเคชัน หลังจากหยุดเซสชัน Instruments จะรวมตัวอย่างและแสดงว่าเมธอดและฟังก์ชันใดใช้เวลามากที่สุด ผลลัพธ์จะแสดงเป็น Call Tree — ต้นไม้เรียกที่เรียงลำดับตาม Self Weight
เมตริกหลักของ Time Profiler คือ Self Weight (เวลาที่ใช้ในเมธอดโดยตรง ไม่รวมการเรียกเมธอดลูก) Self Weight นี่เองที่แสดงว่าฟังก์ชันใดกำลังโหลดโปรเซสเซอร์จริงๆ Weight (เวลาทั้งหมดรวมเมธอดลูก) อาจทำให้เข้าใจผิด: เมธอดที่มี Weight สูงอาจเพียงแค่เรียกเมธอดอื่นที่ช้า ในขณะที่ตัวมันเองเร็ว
import UIKit
class ImageGalleryViewController: UIViewController {
// Time Profiler จะแสดงว่า cellForItemAt มี Self Weight = 40%
// ภายในนั้น decodeImage ใช้ 35% — นี่คือปัญหาคอขวด
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "ImageCell",
for: indexPath
) as! ImageCell
// ❌ decodeImage — ปัญหาคอขวด (Self Weight = 35%)
cell.imageView.image = UIImage(contentsOfFile: imagePath)
return cell
}
}
เมื่อวิเคราะห์ Time Profiler ให้ใส่ใจกับเมธอดที่ทำงานใน com.apple.main-thread หาก Self Weight บนเธรดหลักเกินเกณฑ์ 16 ms ต่อเฟรม — UI จะช้าลง วิธีแก้ปัญหาดังกล่าวคือการย้ายการถอดรหัสรูปภาพ การคำนวณเลย์เอาต์ และการประมวลผลข้อมูลจากเธรดหลักไปยังเธรดพื้นหลังผ่าน Grand Central Dispatch (GCD)
Call Tree — เป็นการแสดงลำดับชั้นของการเรียกเมธอดทั้งหมด เรียงตาม Self Weight เมธอดที่หนักที่สุดใน Call Tree คือบรรทัดแรก การขยายบรรทัดจะแสดงให้เห็นว่าเมธอดนี้เรียกเมธอดลูกใดบ้างและใช้เวลาเท่าใด ค้นหาเมธอดที่ Self Weight (เวลาของตัวเอง) เกิน Weight (เวลาทั้งหมด) อย่างมีนัยสำคัญ — นี่คือสัญญาณของการบล็อกแบบซิงโครนัสและการรอ
Allocations — เป็นเครื่องมือสำหรับตรวจสอบการจัดสรรหน่วยความจำทั้งหมดของแอปพลิเคชัน มันแสดงให้เห็นว่าออบเจ็กต์ใด จำนวนเท่าใด และขนาดรวมเท่าใดที่ถูกสร้างขึ้นในแต่ละช่วงเวลา ต่างจาก Memory Profiler ใน Android Studio ตรงที่ Allocations รองรับ Heapshot — ภาพรวมชั่วขณะของออบเจ็กต์ที่มีชีวิตพร้อมความสามารถในการเปรียบเทียบสองภาพรวม
อินเทอร์เฟซของ Allocations ประกอบด้วยสองส่วนหลัก: All Allocations (สถิติรวมตามประเภทออบเจ็กต์) และ Call Trees (ต้นไม้เรียกพร้อมการแจกแจงตามเมธอดที่สร้างออบเจ็กต์) หากต้องการหารั่วไหล ให้ใช้ Heapshot Analysis: ถ่ายภาพรวมก่อนดำเนินการสถานการณ์ ดำเนินการสถานการณ์ ถ่ายภาพรวมหลังจากนั้น — และเปรียบเทียบว่าออบเจ็กต์ใหม่ใดยังคงอยู่ในหน่วยความจำ
ตาม Apple Developer Documentation แล้ว รูปแบบการรั่วไหลที่พบบ่อยที่สุดที่ตรวจพบผ่าน Allocations คือการสร้าง UIView และ CALayer มากเกินไปเมื่อเลื่อนคอลเลกชัน หากทุกครั้งที่เลื่อน จำนวน UIView ที่มีชีวิตเพิ่มขึ้น แต่คอลเลกชันใช้เซลล์ซ้ำ — แสดงว่ามีการสร้างวิวเพิ่มเติมโดยไม่ปล่อยวิวเก่า Allocations แสดงสแต็กเรียกที่แน่นอนว่าวิวเหล่านี้ถูกสร้างขึ้นที่ใด
| พารามิเตอร์ | คำอธิบาย | สิ่งที่ต้องดู |
|---|---|---|
| # Living | จำนวนออบเจ็กต์ที่มีชีวิตของประเภทนี้ | ควรคงที่เมื่อทำสถานการณ์ซ้ำ |
| # Transient | ออบเจ็กต์ที่สร้างและปล่อยในช่วงเวลา | การเพิ่มขึ้นอย่างกะทันหัน — สัญญาณของการจัดสรรเกิน |
| Total Bytes | ปริมาณหน่วยความจำรวมของประเภทนี้ | เปรียบเทียบกับ RAM ที่มีอยู่ทั้งหมดของอุปกรณ์ |
Heapshot — เป็นภาพรวมชั่วขณะของออบเจ็กต์ที่มีชีวิตใน Allocations ถ่าย Heapshot ก่อนดำเนินการสถานการณ์ ดำเนินการสถานการณ์ และถ่าย Heapshot ที่สอง ความแตกต่างระหว่างภาพรวมจะแสดงว่าออบเจ็กต์ใดถูกสร้างขึ้นและไม่ถูกปล่อย ผลลัพธ์ที่เหมาะสมที่สุด — การเพิ่มขึ้นเฉพาะออบเจ็กต์ชั่วคราว (Autorelease pool) สำหรับการวิเคราะห์ที่แม่นยำ ให้ใช้การรวมกันของ Allocations + Leaks ในเซสชันเดียว Allocations แสดงว่าออบเจ็กต์ใดไม่ถูกปล่อย และ Leaks — แสดงสาเหตุ (การอ้างอิงแบบแข็งใดที่ยึดไว้) เริ่มเซสชันคู่ทุกครั้งที่สงสัยว่ามีการรั่วไหล
Leaks — เป็นเครื่องมือเฉพาะสำหรับการตรวจจับหน่วยความจำรั่วไหลในแอปพลิเคชัน iOS และ macOS ต่างจาก Allocations ที่แสดงเฉพาะการจัดสรร Leaks จะสแกน heap อย่างกระตือรือร้นเพื่อค้นหา retain cycles — สถานการณ์ที่ออบเจ็กต์สองตัวขึ้นไปยึดซึ่งกันและกันด้วยการอ้างอิงแบบแข็ง
Leaks ทำงานร่วมกับ Cycles & Roots — ตัวสร้างภาพของกราฟการยึดออบเจ็กต์ เมื่อตรวจพบการรั่วไหล Leaks จะแสดงออบเจ็กต์ทั้งหมดในวงจร retain count และฟิลด์ที่แน่นอนที่การอ้างอิงถูกส่งผ่าน นักพัฒนาเพียงแค่ดูกราฟและเข้าใจว่าการอ้างอิงใดต้องเปลี่ยนเป็น weak
เครื่องมือจะเน้นการรั่วไหลด้วยเครื่องหมายสีแดงบนไทม์ไลน์โดยอัตโนมัติ Leaks ทำงานแบบเรียลไทม์: ทันทีที่ระบบตรวจพบการรั่วไหล มันจะส่งสัญญาณถึงนักพัฒนาทันที ซึ่งช่วยให้แก้ไขปัญหา “ตรงจุด” โดยไม่ต้องรอ dump และการวิเคราะห์ภายหลัง
ตาม WWDC 2022 แล้ว Leaks สามารถตรวจจับ retain cycles แบบหลายระดับที่ซับซ้อนได้ — ตัวอย่างเช่น เมื่อออบเจ็กต์สามตัวขึ้นไปสร้างห่วงโซ่ปิดของการอ้างอิงแบบแข็ง สำหรับการวินิจฉัยวงจรดังกล่าว กราฟ Cycles & Roots เป็นสิ่งที่ขาดไม่ได้: มันแสดงให้เห็นว่าออบเจ็กต์อ้างอิงซึ่งกันและกันอย่างไร
แต่ละโหนดของกราฟคือออบเจ็กต์ แต่ละลูกศรคือการอ้างอิงแบบแข็ง วงจรคือวงปิดของลูกศร สีของโหนดแสดงสถานะ: สีแดง — ออบเจ็กต์ที่รั่วไหล สีเขียว — ราก (GC Root) สีเทา — ออบเจ็กต์กลาง เพื่อแก้ไขการรั่วไหล ให้หาลูกศรที่สามารถทำให้เป็น weak โดยไม่ทำลายตรรกะ — และเปลี่ยนประเภทการอ้างอิงในโค้ด
Energy Log — เป็นเทมเพลต Instruments สำหรับวัดการใช้พลังงานของแอปพลิเคชัน มันเก็บข้อมูลจากเซ็นเซอร์ฮาร์ดแวร์ของอุปกรณ์: โหลด CPU, สถานะ Wi-Fi และวิทยุเซลลูลาร์, การใช้ GPS, จอแสดงผล และ Bluetooth Energy Log แสดงว่าการดำเนินการใดในแอปพลิเคชันทำให้เกิดการใช้แบตเตอรี่มากที่สุด และซ้อนทับบนกราฟการใช้พลังงานตามช่วงเวลา
เครื่องมือจัดประเภทการดำเนินการตาม ระดับการใช้พลังงาน: ต่ำ (การทำงานของโปรเซสเซอร์ปกติ), ปานกลาง (การส่งสัญญาณ Wi-Fi), สูง (GPS, เครือข่ายมือถือ, GPU) หาก Energy Log แสดงตัวบ่งชี้สีแดงระดับสูงเป็นเวลานาน — แอปพลิเคชันกำลังคายประจุแบตเตอรี่ในพื้นหลังและจะถูกลบโดยผู้ใช้
ปัญหาทั่วไปที่ตรวจพบโดย Energy Log: WakeLock โดยไม่มีข้อจำกัดด้านเวลา (แอปพลิเคชันทำให้โปรเซสเซอร์ทำงานต่อหลังจากเสร็จสิ้นงาน), Location Updates ที่มีความแม่นยำสูง ในพื้นหลัง (ขอพิกัดทุกไม่กี่วินาที), ความผิดปกติของเซสชันเครือข่าย (การเชื่อมต่อใหม่กับเซิร์ฟเวอร์บ่อยครั้ง) Energy Log แนะนำให้บันทึกทุกเหตุการณ์ดังกล่าวและเพิ่มเงื่อนไขในการปิดการดำเนินการที่ใช้พลังงานสูง
สำหรับการทดสอบการใช้พลังงาน ให้ใช้อุปกรณ์จริงที่ใช้พลังงานแบตเตอรี่ — บนอีมูเลเตอร์ ตัวบ่งชี้การใช้พลังงานไม่ถูกต้อง เรียกใช้ Energy Log พร้อมกับการทดสอบ UI เพื่อตรวจสอบการใช้แบตเตอรี่ใน CI โดยอัตโนมัติ
การเริ่มต้น Instruments ทำได้จาก Xcode สองวิธี: ผ่านเมนู Product → Profile (⌘I) หรือเปิด Instruments เป็นแอปพลิเคชันแยกต่างหากใน Launchpad วิธีแรกสะดวกกว่า: Xcode จะคอมไพล์แอปพลิเคชันในโหมดโปรไฟล์โดยอัตโนมัติและเรียกใช้บนอุปกรณ์ที่เชื่อมต่อกับเทมเพลตที่เลือก หลังจากหยุดเซสชัน Instruments จะบันทึกการติดตามในไฟล์ที่มีนามสกุล .trace
การตีความผลลัพธ์ขึ้นอยู่กับเทมเพลต สำหรับ Time Profiler ให้ดู Call Tree ที่เรียงตาม Self Weight — เมธอดที่อยู่ด้านบนสุดคือปัญหาคอขวดหลักของคุณ สำหรับ Allocations — ดู # Living หลังจากสถานการณ์แบบวนรอบ: หากจำนวนออบเจ็กต์เพิ่มขึ้น — ให้หารั่วไหล สำหรับ Leaks — ดูเครื่องหมายสีแดงและกราฟ Cycles & Roots เปรียบเทียบผลลัพธ์ก่อนและหลังการปรับปรุง — นี่เป็นวิธีเดียวที่จะยืนยันประสิทธิภาพของการเปลี่ยนแปลง
// บรรทัดคำสั่งสำหรับ Instruments ใน CI
// การรวม Instruments ในไปป์ไลน์ CI/CD
import XCTest
class PerformanceTests: XCTestCase {
func testScrollPerformance() {
// การวัดเวลาเลื่อนคอลเลกชัน
measure(metrics: [XCTCPUMetric(), XCTMemoryMetric()]) {
app.scrollToBottom()
}
}
}
ใน CI สามารถเรียกใช้ Instruments จากบรรทัดคำสั่งผ่าน xcodebuild -showBuildSettings และ xcrun xctrace ซึ่งช่วยให้การโปรไฟล์อัตโนมัติในทุก commit และไม่พลาดการถดถอย สำหรับการวิเคราะห์ ให้ใช้การเปรียบเทียบ Baseline: หากเมตริกแย่ลง 5% เมื่อเทียบกับ commit ก่อนหน้า — pipeline ควรหยุด
ข้อผิดพลาดหลักเมื่อทำงานกับ Instruments: การโปรไฟล์บนซิมิวเลเตอร์แทนอุปกรณ์จริง (ข้อมูล CPU และ GPU ไม่ถูกต้อง), การเก็บข้อมูลโดยไม่มีสถานการณ์ (ผลลัพธ์แบบสุ่ม), การละเลย Call Tree (ดูเฉพาะกราฟ ไม่ดูเมธอดเฉพาะ) การแก้ไขข้อผิดพลาดเหล่านี้ทำให้ได้คุณภาพการโปรไฟล์ 80%
คำถามที่พบบ่อย
ได้ Instruments รองรับ SwiftUI อย่างเต็มที่ สำหรับการวิเคราะห์ประสิทธิภาพ UI ให้ใช้เทมเพลต Core Animation — มันแสดงความเร็วการเรนเดอร์เฟรมและระบุการเรนเดอร์ View ซ้ำที่ไม่จำเป็น Time Profiler และ Allocations ก็ทำงานกับ SwiftUI ได้โดยไม่มีข้อจำกัด
Instruments — เป็นโปรไฟล์เลอร์สากลสำหรับระบบนิเวศ Apple ทั้งหมด ครอบคลุม CPU, หน่วยความจำ, เครือข่าย, กราฟิก และการใช้พลังงาน Shark — เป็นตัววิเคราะห์ heap dump ภายในใน LeakCanary ที่เชี่ยวชาญเฉพาะในการค้นหาหน่วยความจำรั่วไหลบน Android
Instruments ไม่ถูกฝังในโค้ดแอปพลิเคชัน — เป็นเครื่องมือภายนอกที่เชื่อมต่อกับกระบวนการที่กำลังทำงานผ่าน Xcode ไม่จำเป็นต้องเปลี่ยนแปลงโค้ดใดๆ ไฟล์ .trace เป็นเพียงล็อกที่ไม่รวมอยู่ในไบนารี
ที่อัตราการสุ่มตัวอย่างมาตรฐาน 1 ms โอเวอร์เฮดของ Time Profiler น้อยกว่า 3% ในโหมดติดตามที่แม่นยำ (ทุกการเรียกฟังก์ชัน) โอเวอร์เฮดอาจถึง 20-30% ดังนั้นสำหรับการโปรไฟล์ประจำวันจึงใช้การสุ่มตัวอย่าง การติดตามที่แม่นยำจำเป็นเฉพาะส่วนที่สำคัญเท่านั้น
ผลลัพธ์จะถูกบันทึกในไฟล์ .trace ในโฟลเดอร์โปรเจกต์โดยอัตโนมัติ ไฟล์สามารถเปิดบน Mac เครื่องอื่นด้วย Xcode สำหรับการวิเคราะห์ร่วมกัน สำหรับการส่งออกในรูปแบบข้อความ ให้ใช้ xcrun xctrace export --input file.trace --output result.xml
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม