View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Todos los videos
  • Información

Más videos

  • Información
  • Resumen
  • Código
  • Mejora el uso y el rendimiento de la memoria con Swift

    Descubre formas de mejorar el rendimiento y la gestión de la memoria de tu código Swift. Exploraremos formas de perfeccionar tu código, desde realizar cambios algorítmicos de alto nivel hasta adoptar InlineArray y Span, para un control preciso de la memoria y las asignaciones.

    Capítulos

    • 0:00 - Introducción y agenda
    • 1:19 - App de formato y parser QOI
    • 2:25 - Algoritmos
    • 8:17 - Asignaciones
    • 16:30 - Exclusividad
    • 19:12 - Pila contra montón
    • 21:08 - Recuento de referencias
    • 29:52 - Biblioteca de análisis binario Swift
    • 31:03 - Próximos pasos

    Recursos

    • Swift Binary Parsing
    • Performance and metrics
    • The Swift website
    • The Swift Programming Language
      • Video HD
      • Video SD

    Videos relacionados

    WWDC25

    • Crear perfiles y optimizar el uso de energía en tu app
    • Novedades de Swift
    • Optimiza el rendimiento del CPU con instrumentos

    WWDC24

    • Explore Swift performance
  • Buscar este video…
    • 7:01 - Corrected Data.readByte() method

      import Foundation
      
      extension Data {
        /// Consume a single byte from the start of this data.
        mutating func readByte() -> UInt8? {
          guard !isEmpty else { return nil }
          return self.popFirst()
        }
      }
    • 9:56 - RGBAPixel.data(channels:) method

      extension RGBAPixel {
        /// Returns the RGB or RGBA values for this pixel, as specified
        /// by the given channels information.
        func data(channels: QOI.Channels) -> some Collection<UInt8> {
          switch channels {
          case .rgb:
            [r, g, b]
          case .rgba:
            [r, g, b, a]
          }
        }
      }
    • 10:21 - Original QOIParser.parseQOI(from:) method

      extension QOIParser {
        /// Parses an image from the given QOI data.
        func parseQOI(from input: inout Data) -> QOI? {
          guard let header = QOI.Header(parsing: &input) else { return nil }
          
          let pixels = readEncodedPixels(from: &input)
            .flatMap { decodePixels(from: $0) }
            .prefix(header.pixelCount)
            .flatMap { $0.data(channels: header.channels) }
      
          return QOI(header: header, data: Data(pixels))
        }
      }
    • 12:53 - Revised QOIParser.parseQOI(from:) method

      extension QOIParser {
        /// Parses an image from the given QOI data.
        func parseQOI(from input: inout Data) -> QOI? {
          guard let header = QOI.Header(parsing: &input) else { return nil }
          
          let totalBytes = header.pixelCount * Int(header.channels.rawValue)
          var pixelData = Data(repeating: 0, count: totalBytes)
          var offset = 0
          
          while offset < totalBytes {
            guard let nextPixel = parsePixel(from: &input) else { break }
            
            switch nextPixel {
            case .run(let count):
              for _ in 0..<count {
                state.previousPixel
                  .write(to: &pixelData, at: &offset, channels: header.channels)
              }
            default:
              decodeSinglePixel(from: nextPixel)
                .write(to: &pixelData, at: &offset, channels: header.channels)
            }
          }
          
          return QOI(header: header, data: pixelData)
        }
      }
    • 15:07 - Array behavior

      var array = [1, 2, 3]
      array.append(4)
      array.removeFirst()
      // array == [2, 3, 4]
      
      var copy = array
      copy[0] = 10      // copy happens on mutation
      // array == [2, 3, 4]
      // copy == [10, 3, 4]
    • 19:47 - InlineArray behavior (part 1)

      var array: InlineArray<3, Int> = [1, 2, 3]
      array[0] = 4
      // array == [4, 2, 3]
      
      // Can't append or remove elements
      array.append(4)
      // error: Value of type 'InlineArray<3, Int>' has no member 'append'
      
      // Can only assign to a same-sized inline array
      let bigger: InlineArray<6, Int> = array
      // error: Cannot assign value of type 'InlineArray<3, Int>' to type 'InlineArray<6, Int>'
    • 20:23 - InlineArray behavior (part 2)

      var array: InlineArray<3, Int> = [1, 2, 3]
      array[0] = 4
      // array == [4, 2, 3]
      
      var copy = array    // copy happens on assignment
      for i in copy.indices {
          copy[i] += 10
      }
      // array == [4, 2, 3]
      // copy == [14, 12, 13]
    • 23:13 - processUsingBuffer() function

      // Safe usage of a buffer pointer
      func processUsingBuffer(_ array: [Int]) -> Int {
          array.withUnsafeBufferPointer { buffer in
              var result = 0
              for i in 0..<buffer.count {
                  result += calculate(using: buffer, at: i)
              }
              return result
          }
      }
    • 23:34 - Dangerous getPointerToBytes() function

      // Dangerous - DO NOT USE!
      func getPointerToBytes() -> UnsafePointer<UInt8> {
          let array: [UInt8] = Array(repeating: 0, count: 128)
          // DANGER: The next line escapes a pointer
          let pointer = array.withUnsafeBufferPointer { $0.baseAddress! }
          // DANGER: The next line returns the escaped pointer
          return pointer
      }
    • 24:46 - processUsingSpan() function

      // Safe usage of a span
      @available(macOS 16.0, *)
      func processUsingSpan(_ array: [Int]) -> Int {
          let intSpan = array.span
          var result = 0
          for i in 0..<intSpan.count {
              result += calculate(using: intSpan, at: i)
          }
          return result
      }
    • 25:07 - getHiddenSpanOfBytes() function (attempt 1)

      @available(macOS 16.0, *)
      func getHiddenSpanOfBytes() -> Span<UInt8> { }
      // error: Cannot infer lifetime dependence...
    • 25:28 - getHiddenSpanOfBytes() function (attempt 2)

      @available(macOS 16.0, *)
      func getHiddenSpanOfBytes() -> () -> Int {
          let array: [UInt8] = Array(repeating: 0, count: 128)
          let span = array.span
          return { span.count }
      }
    • 26:27 - RawSpan.readByte() method

      @available(macOS 16.0, *)
      extension RawSpan {
        mutating func readByte() -> UInt8? {
          guard !isEmpty else { return nil }
          
          let value = unsafeLoadUnaligned(as: UInt8.self)
          self = self._extracting(droppingFirst: 1)
          return value
        }
      }
    • 28:02 - Final QOIParser.parseQOI(from:) method

      /// Parses an image from the given QOI data.
      mutating func parseQOI(from input: inout RawSpan) -> QOI? {
        guard let header = QOI.Header(parsing: &input) else { return nil }
        
        let totalBytes = header.pixelCount * Int(header.channels.rawValue)
        
        let pixelData = Data(rawCapacity: totalBytes) { outputSpan in
          while outputSpan.count < totalBytes {
            guard let nextPixel = parsePixel(from: &input) else { break }
            
            switch nextPixel {
            case .run(let count):
              for _ in 0..<count {
                previousPixel
                  .write(to: &outputSpan, channels: header.channels)
              }
              
            default:
              decodeSinglePixel(from: nextPixel)
                .write(to: &outputSpan, channels: header.channels)
              
            }
          }
        }
        
        return QOI(header: header, data: pixelData)
      }
    • 28:31 - RGBAPixel.write(to:channels:) method

      @available(macOS 16.0, *)
      extension RGBAPixel {
        /// Writes this pixel's RGB or RGBA data into the given output span.
        @lifetime(&output)
        func write(to output: inout OutputRawSpan, channels: QOI.Channels) {
          output.append(r)
          output.append(g)
          output.append(b)
          
          if channels == .rgba {
            output.append(a)
          }
        }
      }
    • 0:00 - Introducción y agenda
    • Obtenga información sobre cómo optimizar el rendimiento de las apps y bibliotecas de código Swift utilizando Swift 6.2. Los nuevos tipos 'InlineArray' y 'Span' reducen las asignaciones, las comprobaciones de exclusividad y el recuento de referencias. Se presenta una nueva biblioteca Swift de código abierto, Binary Parsing, para un análisis binario rápido y seguro.

    • 1:19 - App de formato y parser QOI
    • La app de esta sesión de la WWDC25 carga imágenes en formato QOI, un formato simple y sin pérdidas con una especificación de una sola página. El analizador de imágenes de la app gestiona varios métodos de codificación de píxeles. Luego, la app carga instantáneamente un pequeño archivo de ícono, pero tarda unos segundos en cargar una foto más grande de un pájaro.

    • 2:25 - Algoritmos
    • Cuando las apps trabajan con datos del mundo real, a menudo pueden surgir problemas de rendimiento debido al uso incorrecto de algoritmos o estructuras de datos. Para identificar y abordar estos problemas, puede utilizar Instrumentos, que tiene plantillas de instrumentos para analizar asignaciones y liberaciones e identificar código ineficiente con perfiladores. La herramienta Time Profiler es especialmente útil para problemas de rendimiento. Al analizar las llamadas capturadas y los seguimientos de pila, puede identificar las áreas donde las apps pasan la mayor parte del tiempo. En el ejemplo, se gastó una cantidad significativa de tiempo en una llamada del sistema para copiar datos, 'platform_memmove'. Mediante el uso de instrumentos, este ejemplo analiza un método personalizado llamado "readByte". Este método se agregó a una extensión del tipo 'Datos', lo que provocó una copia excesiva de datos binarios. El ejemplo reemplaza el método con el método 'popFirst()' más eficiente, que reduce los datos del frente de una secuencia sin copiar. Este cambio resolvió el problema de rendimiento en el método 'readByte'. Después de realizar el cambio, el ejemplo ejecutó el perfil nuevamente y la barra significativa 'platform_memmove' desapareció del gráfico de llama. La evaluación comparativa mostró una aceleración sustancial y la relación entre el tamaño de la imagen y el tiempo de análisis cambió de cuadrática a lineal, lo que indica un algoritmo más eficiente.

    • 8:17 - Asignaciones
    • Se vuelve a perfilar la app para descubrir que el analizador de imágenes genera asignaciones y desasignaciones de memoria excesivas, en particular cuando involucran matrices. La gran cantidad de asignaciones, casi un millón para analizar una sola imagen, indica un problema crítico. La mayoría de estas asignaciones son transitorias y de corta duración, lo que sugiere que pueden optimizarse. Para identificar la fuente de estas asignaciones innecesarias, el ejemplo utiliza el instrumento Asignaciones en Instrumentos. El análisis revela que un método llamado 'RGBAPixel.data(channels:)' es el principal culpable. Este método crea una matriz cada vez que se llama, lo que genera una cantidad sustancial de asignaciones. La estructura del código, que implica una cadena compleja de métodos 'flatMap' y 'prefix', contribuye al problema. Cada paso de esta cadena genera nuevas asignaciones a medida que las matrices se crean, se aplanan y se copian repetidamente. Si bien este enfoque es conciso, no es eficiente en el uso de la memoria. Para solucionar este problema, el ejemplo reescribe la función de análisis. En lugar de depender de asignaciones intermedias, calcula de antemano el tamaño total de los datos del resultado y asigna un único búfer. Este enfoque elimina la necesidad de asignaciones repetidas durante el proceso de decodificación.

    • 16:30 - Exclusividad
    • El rendimiento de la app mejoró tanto que los instrumentos de creación de perfiles necesitaban más datos. Después de repetir el código de análisis 50 veces, los resultados mostraron los símbolos 'swift_beginAccess' y 'swift_endAccess' que indican pruebas de exclusividad. Estas pruebas de exclusividad fueron causadas por propiedades en la clase 'State' anidadas dentro de la estructura 'QOIParser', que el ejemplo luego mueve directamente al tipo de analizador padre para eliminar las verificaciones de exclusividad. Después de algunos ajustes del compilador, la verificación de exclusividad se eliminó por completo, como lo verificó una nueva ejecución del perfil.

    • 19:12 - Pila contra montón
    • El ejemplo reemplaza el uso de 'Array' en la app con 'InlineArray', una colección de tamaño fijo almacenada en línea, que optimiza el uso de la memoria al eliminar el conteo de referencias y las verificaciones de exclusividad. Es ideal para el caché de píxeles ・€・ una matriz de 64 elementos que nunca cambia de tamaño y se modifica en el lugar, lo que mejora el rendimiento sin la necesidad de copiar o compartir referencias.

    • 21:08 - Recuento de referencias
    • En el ejemplo de optimización final de la app, el ejemplo utiliza los nuevos tipos "Span" para mejorar el rendimiento y mejorar la seguridad de la memoria. En Instrumentos, se utiliza el gráfico de llama del análisis del Perfilador de tiempo. Los datos perfilados se centran en 'QOIParser' y encuentran que se dedica un tiempo significativo a operaciones de conteo de referencias, particularmente con el tipo 'Datos' debido a su semántica de copia en escritura. 'Span' y sus tipos relacionados son una nueva forma de trabajar con memoria contigua en una colección. Utilizan la característica no escapable de Swift ('~Escapable'), que vincula sus duraciones de vida a la colección, lo que garantiza la seguridad de la memoria y elimina la necesidad de una gestión manual de la memoria. Esto permite un acceso eficiente a la memoria sin los riesgos asociados con los punteros inseguros. El ejemplo demuestra cómo utilizar los tipos 'Span' para reescribir métodos existentes, haciéndolos más simples, más seguros y con mayor rendimiento. En los métodos de análisis de imágenes, 'Datos' se reemplaza por 'RawSpan' y la sobrecarga del recuento de referencias se reduce enormemente. Además, se adopta 'OutputSpan' en el proceso de análisis para una mayor optimización, lo que hace que la operación de análisis sea seis veces más rápida que antes sin recurrir a punteros inseguros.

    • 29:52 - Biblioteca de análisis binario Swift
    • Swift Binary Parsing le permite crear analizadores seguros y eficientes para formatos binarios. Ofrece herramientas para gestionar diversos aspectos de seguridad, incluida la prevención del desbordamiento de enteros, la especificación del signo, el ancho de bits y el orden de bytes y la validación de tipos personalizados. La biblioteca ya se encuentra en uso en Apple y está disponible públicamente para que puedas probarla y contribuir a través de los foros de Swift y GitHub.

    • 31:03 - Próximos pasos
    • Las conclusiones clave incluyen: Uso de Xcode e instrumentos para crear perfiles de apps. Analizar el rendimiento de los algoritmos para identificar cuellos de botella. Explorando soluciones a lo anterior con los nuevos tipos 'InlineArray' y 'Span' introducidos en Swift 6.2.

Developer Footer

  • Videos
  • WWDC25
  • Mejora el uso y el rendimiento de la memoria con Swift
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines