Swift Academy · Lekcja

Optymalizacja gorących ścieżek: COW, inlining i specjalizacja

Stosowanie @inline, @_specialize i optymalizacji typów wartości na podstawie danych profilera.

Lekcja 4 z 413 kroki

Optymalizacja gorących ścieżek: COW, inlining i specjalizacja to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Identyfikowanie przed optymalizacją

Zawsze należy najpierw wykonać profilowanie. Optymalizować należy wyłącznie kod wskazany przez Time Profiler jako często wykonywana ścieżka — przedwczesna optymalizacja jest stratą czasu.

// Measure → Identify → Optimise → Re-measure
// A 10ms function called once is less important than
// a 0.1ms function called 10,000 times per frame

Copy-on-Write (COW)

Typy wartościowe Swift (Array, Dictionary) używają mechanizmu COW: pamięć jest współdzielona do momentu wykonania mutacji, co pozwala uniknąć niepotrzebnego kopiowania.

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

Zapewnianie COW w typach niestandardowych

Aby zaimplementować COW w niestandardowych typach wartościowych, należy opakować zmienny stan w typ referencyjny i kopiować go przed mutacją.

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)

Wymusza wstawienie funkcji przez kompilator w każdym miejscu jej wywołania, eliminując narzut wywołania w przypadku małych funkcji wykonywanych w ciasnych pętlach.

@inline(__always)
func clamp(_ value: Float, _ min: Float, _ max: Float) -> Float {
  return Swift.max(min, Swift.min(max, value))
}

@inline(never)

Zapobiega wstawianiu funkcji, aby zmniejszyć rozmiar kodu lub wymusić potraktowanie danej ścieżki jako rzadko używanej.

@inline(never)
func handleUnexpectedError(_ error: Error) {
  // Large error-handling block — never inline to keep hot path small
}

@_specialize dla generyków

Informuje kompilator, aby wygenerował wyspecjalizowaną kopię funkcji generycznej dla określonego typu, umożliwiając statyczne wysyłanie i optymalizacje 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 }
}

Optymalizacja całego modułu

WMO (włączone w trybie Release) pozwala kompilatorowi wstawiać funkcje i przeprowadzać specjalizację między granicami plików w obrębie modułu.

// 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

Unikanie narzutu ARC

Częste tworzenie typów referencyjnych w często wykonywanych ścieżkach powoduje narzut związany z retain/release w ARC. Należy preferować typy wartościowe lub buforować odwołania.

// 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() }

Używanie ContiguousArray

ContiguousArray gwarantuje ciągłe przechowywanie elementów (w przeciwieństwie do Array w przypadku elementów będących klasami), co poprawia wydajność pamięci podręcznej w ciasnych pętlach.

var nums = ContiguousArray<Float>(repeating: 0, count: 10_000)
// Faster iteration than Array<Float> for bridged-to-ObjC types

Ograniczanie wyszukiwań w tablicach świadków protokołów

Dynamiczne wysyłanie za pośrednictwem protokołów korzysta z tablic świadków. Generyki i specjalizacja zastępują wyszukiwania w tablicach świadków bezpośrednimi wywołaniami.

// 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

Testowanie wydajności za pomocą XCTMeasure

Zawsze należy weryfikować optymalizacje za pomocą testów wydajności XCTMeasure w zestawie testów, aby zapobiegać regresjom.

func testNormalizePerformance() {
  let data = Array(0..<100_000).map { Float($0) }
  measure {
    _ = normalize(data)
  }
}

Szybkie sprawdzenie

Co sprawdza isKnownUniquelyReferenced(_:) podczas implementowania mechanizmu Copy-on-Write?

Podsumowanie lekcji

Najpierw należy wykonać profilowanie za pomocą Instruments. W przypadku kolekcji należy korzystać z wbudowanego mechanizmu COW języka Swift; w niestandardowych typach wartościowych należy go implementować za pomocą isKnownUniquelyReferenced. @inline(__always) należy stosować w przypadku małych funkcji często wykonywanych, @_specialize w przypadku często wykonywanych fragmentów generycznych, a WMO włączać w kompilacjach Release. Każdą optymalizację należy weryfikować za pomocą testów wydajności XCTMeasure.

Bezpłatny start

Ucz się Swift dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
122
Lekcje
409

Często zadawane pytania

Czy lekcja „Optymalizacja gorących ścieżek: COW, inlining i specjalizacja” jest bezpłatna?

Tak — pełny tekst „Optymalizacja gorących ścieżek: COW, inlining i specjalizacja” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Optymalizacja gorących ścieżek: COW, inlining i specjalizacja”?

Stosowanie @inline, @_specialize i optymalizacji typów wartości na podstawie danych profilera. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Optymalizacja gorących ścieżek: COW, inlining i specjalizacja”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy Instruments: Time Profiler
  2. Instruments Allocations i Leaks
  3. Main Thread Checker i zawieszanie aplikacji
  4. Optymalizacja gorących ścieżek: COW, inlining i specjalizacja
← Powrót do Swift Academy