ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง
ใช้ @inline, @_specialize และการเพิ่มประสิทธิภาพชนิดค่าโดยอ้างอิงข้อมูลจากตัววิเคราะห์ประสิทธิภาพ
ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
ระบุจุดที่ต้องปรับปรุงก่อน
วิเคราะห์ประสิทธิภาพก่อนเสมอ ปรับปรุงเฉพาะโค้ดที่ Time Profiler ระบุว่าเป็นเส้นทางการทำงานที่ใช้ทรัพยากรมาก เพราะการปรับปรุงก่อนเวลาอันควรทำให้เสียเวลา
// Measure → Identify → Optimise → Re-measure
// A 10ms function called once is less important than
// a 0.1ms function called 10,000 times per frameการคัดลอกเมื่อเขียน (COW)
ชนิดค่าใน Swift เช่น อาร์เรย์และพจนานุกรมใช้ COW โดยจะแชร์พื้นที่จัดเก็บจนกว่าจะเกิดการเปลี่ยนแปลง จึงหลีกเลี่ยงการคัดลอกที่ไม่จำเป็น
var a = [1, 2, 3, 4, 5]
var b = a // no copy yet, shared buffer
b.append(6) // copy happens here (b mutates)
print(a.count) // 5 — a unchangedการทำให้ COW ทำงานในชนิดข้อมูลแบบกำหนดเอง
นำ COW มาใช้ในชนิดค่าแบบกำหนดเองโดยห่อสถานะที่เปลี่ยนแปลงได้ไว้ในชนิดอ้างอิง และคัดลอกก่อนเปลี่ยนแปลง
struct Matrix {
private class Storage { var data: [[Double]] }
private var storage = Storage()
private mutating func ensureUnique() {
if !isKnownUniquelyReferenced(&storage) {
storage = Storage(data: storage.data) // copy on write
}
}
mutating func set(row: Int, col: Int, value: Double) {
ensureUnique()
storage.data[row][col] = value
}
}@inline(__always)
บังคับให้คอมไพเลอร์แทรกฟังก์ชันลงในทุกตำแหน่งที่มีการเรียกใช้ เพื่อตัดค่าใช้จ่ายของการเรียกฟังก์ชันขนาดเล็กที่ถูกเรียกในลูปซึ่งทำงานถี่
@inline(__always)
func clamp(_ value: Float, _ min: Float, _ max: Float) -> Float {
return Swift.max(min, Swift.min(max, value))
}@inline(never)
ป้องกันการแทรกฟังก์ชัน เพื่อช่วยลดขนาดโค้ดหรือบังคับให้คอมไพเลอร์ถือว่าเส้นทางนั้นเป็นเส้นทางที่ทำงานน้อย (เกิดขึ้นไม่บ่อย)
@inline(never)
func handleUnexpectedError(_ error: Error) {
// Large error-handling block — never inline to keep hot path small
}@_specialize สำหรับเจเนอริก
สั่งให้คอมไพเลอร์สร้างสำเนาเฉพาะทางของฟังก์ชันเจเนอริกสำหรับชนิดข้อมูลหนึ่งโดยเฉพาะ ทำให้ใช้การส่งคำสั่งแบบคงที่และการปรับปรุงด้วย SIMD ได้
@_specialize(where T == Float)
@_specialize(where T == Double)
func normalize<T: FloatingPoint>(_ values: [T]) -> [T] {
let max = values.max()!
return values.map { $0 / max }
}การปรับปรุงประสิทธิภาพทั้งโมดูล
WMO (เปิดใช้ในรุ่นเผยแพร่) อนุญาตให้คอมไพเลอร์แทรกฟังก์ชันและสร้างรูปแบบเฉพาะทางข้ามขอบเขตไฟล์ภายในโมดูลเดียวกัน
// Xcode: Build Settings → Swift Compiler → Code Generation
// Optimization Level: Optimize for Speed (-O)
// Compilation Mode: Whole Module
// Enables cross-file inlining and dead code eliminationการลดค่าใช้จ่ายของ ARC
การสร้างชนิดอ้างอิงบ่อยครั้งในเส้นทางการทำงานที่ใช้ทรัพยากรมากทำให้เกิดค่าใช้จ่ายจากการเพิ่มและลดการครอบครองของ ARC ให้เลือกใช้ชนิดค่า หรือเก็บการอ้างอิงไว้ใช้ซ้ำ
// HOT PATH:
for _ in 0..<1_000_000 {
let obj = HeavyClass() // alloc + dealloc + ARC overhead
}
// BETTER: allocate once outside the loop
let obj = HeavyClass()
for _ in 0..<1_000_000 { obj.process() }การใช้ ContiguousArray
ContiguousArray รับรองว่าพื้นที่จัดเก็บจะต่อเนื่องกัน (ต่างจาก Array ที่มีองค์ประกอบชนิดคลาส) จึงช่วยเพิ่มประสิทธิภาพแคชในลูปที่ทำงานถี่
var nums = ContiguousArray<Float>(repeating: 0, count: 10_000)
// Faster iteration than Array<Float> for bridged-to-ObjC typesการลดการค้นหาตารางการทำงานตามโพรโทคอล
การส่งคำสั่งแบบไดนามิกของโพรโทคอลใช้ตารางการทำงานตามโพรโทคอล เจเนอริกร่วมกับการสร้างรูปแบบเฉพาะทางจะแทนที่การค้นหาตารางเหล่านี้ด้วยการเรียกโดยตรง
// Dynamic dispatch (slower for hot path):
func process(_ drawable: any Drawable) { drawable.draw() }
// Static dispatch after specialization:
func process<T: Drawable>(_ drawable: T) { drawable.draw() }
// Compiler may devirtualize and inlineการวัดประสิทธิภาพด้วย XCTMeasure
ตรวจสอบการปรับปรุงประสิทธิภาพด้วยการวัดประสิทธิภาพ XCTMeasure ในชุดการทดสอบเสมอ เพื่อป้องกันประสิทธิภาพถดถอย
func testNormalizePerformance() {
let data = Array(0..<100_000).map { Float($0) }
measure {
_ = normalize(data)
}
}ตรวจสอบความเข้าใจ
isKnownUniquelyReferenced(_:) ตรวจสอบอะไรเมื่อนำการคัดลอกเมื่อเขียนมาใช้
ทบทวนบทเรียน
วิเคราะห์ประสิทธิภาพด้วย Instruments ก่อน ใช้ COW ที่มีมาใน Swift สำหรับคอลเลกชัน และนำมาใช้ในชนิดค่าแบบกำหนดเองด้วย isKnownUniquelyReferenced ใช้ @inline(__always) กับฟังก์ชันขนาดเล็กในเส้นทางการทำงานที่ใช้ทรัพยากรมาก ใช้ @_specialize กับจุดที่เจเนอริกใช้ทรัพยากรมาก และเปิดใช้ WMO ในรุ่นเผยแพร่ ตรวจสอบการปรับปรุงทุกครั้งด้วยการวัดประสิทธิภาพ XCTMeasure
คำถามที่พบบ่อย
บทเรียน “ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง”
ใช้ @inline, @_specialize และการเพิ่มประสิทธิภาพชนิดค่าโดยอ้างอิงข้อมูลจากตัววิเคราะห์ประสิทธิภาพ คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน Instruments: ตัววิเคราะห์เวลา
- Instruments สำหรับการจัดสรรและการรั่วไหล
- ตัวตรวจสอบเธรดหลักและการค้าง
- ปรับเส้นทางที่ใช้เวลามาก: COW การแทรกโค้ด และการปรับเฉพาะทาง