0Pricing
Swift Academy · Lección

Optimización de rutas críticas: COW, inlining y especialización

Aplique @inline, @_specialize y optimizaciones de tipos valor basándose en datos del profiler.

Optimización de rutas críticas: COW, inlining y especialización es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

Identificar antes de optimizar

Analice siempre primero. Optimice únicamente el código que Time Profiler identifique como una ruta crítica; optimizar prematuramente hace perder tiempo.

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

Los tipos de valor de Swift (Array y Dictionary) utilizan COW: el almacenamiento se comparte hasta que se produce una mutación, lo que evita copias innecesarias.

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

Garantizar COW en tipos personalizados

Implemente COW en tipos de valor personalizados envolviendo el estado mutable en un tipo de referencia y copiándolo antes de mutarlo.

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)

Fuerza al compilador a insertar una función en cada punto de llamada, eliminando el coste de llamada en funciones pequeñas invocadas dentro de bucles ajustados.

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

@inline(never)

Impide la inserción para reducir el tamaño del código o para obligar al compilador a tratar una ruta como poco frecuente.

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

@_specialize para genéricos

Indica al compilador que genere una copia especializada de una función genérica para un tipo específico, lo que permite el despacho estático y las optimizaciones 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 }
}

Optimización de módulo completo

WMO (activada en Release) permite al compilador insertar y especializar código entre los límites de los archivos dentro de un módulo.

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

Evitar el coste de ARC

La creación frecuente de tipos de referencia en rutas críticas provoca un coste adicional de retención y liberación de ARC. Prefiera tipos de valor o almacene en caché las referencias.

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

Usar ContiguousArray

ContiguousArray garantiza un almacenamiento contiguo (a diferencia de Array para elementos de clase), lo que mejora el rendimiento de la caché en bucles ajustados.

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

Reducir las búsquedas en tablas de testigos de protocolos

El despacho dinámico de protocolos utiliza tablas de testigos. Los genéricos y la especialización reemplazan las búsquedas en tablas de testigos por llamadas directas.

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

Crear comparativas con XCTMeasure

Valide siempre las optimizaciones con comparativas de XCTMeasure en el conjunto de pruebas para evitar regresiones.

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

Comprobación rápida

¿Qué comprueba isKnownUniquelyReferenced(_:) al implementar Copy-on-Write?

Resumen de la lección

Analice primero con Instruments. Confíe en el COW integrado de Swift para las colecciones; impleméntelo en tipos de valor personalizados con isKnownUniquelyReferenced. Use @inline(__always) para funciones pequeñas de rutas críticas, @_specialize para puntos críticos genéricos y active WMO en las compilaciones Release. Valide cada optimización con comparativas de XCTMeasure.

Preguntas frecuentes

¿La lección «Optimización de rutas críticas: COW, inlining y especialización» es gratis?

Sí — el texto completo de «Optimización de rutas críticas: COW, inlining y especialización» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Optimización de rutas críticas: COW, inlining y especialización»?

Aplique @inline, @_specialize y optimizaciones de tipos valor basándose en datos del profiler. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Optimización de rutas críticas: COW, inlining y especialización»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Fundamentos de Instruments: Time Profiler
  2. Instruments Allocations y Leaks
  3. Main Thread Checker y bloqueos
  4. Optimización de rutas críticas: COW, inlining y especialización
← Volver a Swift Academy