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
 

Vídeos

Abrir menu Fechar menu
  • Coleções
  • Todos os vídeos
  • Sobre

Mais vídeos

  • Sobre
  • Resumo
  • Código
  • Melhore o uso da memória e o desempenho com o Swift

    Descubra maneiras de melhorar o desempenho e o gerenciamento de memória do seu código Swift. Vamos explorar maneiras de aprimorar seu código, desde alterações algorítmicas avançadas até o uso dos novos tipos de InlineArray e Span, que oferecem um controle mais preciso sobre a memória e as alocações.

    Capítulos

    • 0:00 - Introdução
    • 1:19 - App: Formato QOI e parser
    • 2:25 - Algoritmos
    • 8:17 - Alocações
    • 16:30 - Exclusividade
    • 19:12 - Pilha x heap
    • 21:08 - Contagem de referências
    • 29:52 - Biblioteca de análise binária do Swift
    • 31:03 - Próximas etapas

    Recursos

    • Swift Binary Parsing
    • Performance and metrics
    • The Swift website
    • The Swift Programming Language
      • Vídeo HD
      • Vídeo SD

    Vídeos relacionados

    WWDC25

    • Monitore e otimize o consumo de energia do seu app
    • Novidades do Swift
    • Otimize o desempenho da CPU com o Instruments

    WWDC24

    • Explore Swift performance
  • Buscar neste vídeo...
    • 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 - Introdução
    • Aprenda a otimizar o desempenho de apps e bibliotecas em Swift usando o Swift 6.2. Os novos tipos 'InlineArray' e 'Span' reduzem alocações, verificações de exclusividade e contagem de referências. Uma nova biblioteca de código aberto para Swift, Binary Parsing, foi lançada para análise binária rápida e segura.

    • 1:19 - App: Formato QOI e parser
    • O app desta sessão da WWDC25 carrega imagens no formato QOI, formato sem perdas com especificação de página única. O parser de imagens aceita vários métodos de codificação de pixels. O app carrega instantaneamente um ícone pequeno, mas demora alguns segundos para carregar uma foto maior.

    • 2:25 - Algoritmos
    • Quando apps lidam com dados reais, problemas de desempenho podem ocorrer devido ao uso incorreto de algoritmos ou estruturas de dados. Para identificar e resolver esses problemas, use o Instruments, que tem modelos para analisar alocações e liberações, além de identificar código ineficiente com criadores de perfil. O instrumento Time Profiler é útil para identificar problemas de desempenho. Ao analisar as chamadas capturadas e as pilhas de execução, identifique as áreas onde os apps gastam mais tempo. Uma parte do tempo foi gasta em uma chamada de sistema para copiar dados, o 'platform_memmove'. Usando o Instruments, este exemplo analisa um método personalizado chamado 'readByte'. Esse método foi adicionado a uma extensão do tipo 'Data', o que causou cópias excessivas dos dados binários. No exemplo, o método foi substituído pelo mais eficiente 'popFirst()', que reduz os dados do início de uma sequência sem realizar cópias. Essa alteração resolveu o problema de desempenho no método 'readByte'. Após a alteração, o exemplo executou a análise de desempenho novamente, e a barra significativa do 'platform_memmove' desapareceu do gráfico de chamas. Os testes de desempenho mostraram aumento na velocidade, e a relação entre o tamanho da imagem e o tempo de análise mudou de quadrática para linear, com um algoritmo mais eficiente.

    • 8:17 - Alocações
    • O app foi novamente analisado com ferramentas de profiling e constatou-se que o parser de imagens causa alocações e desalocações excessivas de memória envolvendo matrizes. O alto número de alocações, quase um milhão para analisar uma única imagem, indica um problema crítico. A maioria dessas alocações é transitória, de curta duração, podendo ser otimizada. Para identificar a origem dessas alocações desnecessárias, o exemplo utiliza o instrumento Allocations no Instruments. A análise revela que um método chamado 'RGBAPixel.data(channels:)' é o principal responsável. Esse método cria uma matriz toda vez que é chamada, causando um número substancial de alocações. A estrutura do código, que envolve uma cadeia complexa de métodos 'flatMap' e 'prefix', contribui para o problema. Cada etapa dessa cadeia gera novas alocações, pois as matrizes são criadas, niveladas e copiadas repetidamente. Embora a abordagem seja concisa, não é eficiente em termos de memória. Para resolver esse problema, o exemplo reescreve a função de análise. Em vez de depender de alocações intermediárias, ela calcula o tamanho total dos dados resultantes e aloca um único buffer. Essa abordagem elimina a necessidade de alocações repetidas durante o processo de decodificação.

    • 16:30 - Exclusividade
    • O desempenho do app melhorou tanto que os instrumentos de profiling precisaram de mais dados. Após executar o código de análise 50 vezes, os resultados mostraram os 'swift_beginAccess' e 'swift_endAccess', que indicam testes de exclusividade. Esses testes de exclusividade foram causados por propriedades na classe 'State', aninhada dentro do 'QOIParser'. O exemplo move essas propriedades para o tipo pai do parser para eliminar os testes de exclusividade. Após ajustes no compilador, a verificação de exclusividade foi eliminada, conforme verificado em uma nova execução de análise de desempenho.

    • 19:12 - Pilha x heap
    • O exemplo substitui o uso de 'Array' pelo 'InlineArray', uma coleção de tamanho fixo armazenada em linha, que otimiza o uso de memória eliminando a contagem de referências e os testes de exclusividade. É ideal para o cache de pixels, uma matriz de 64 elementos que não muda de tamanho e é modificada no lugar, melhorando o desempenho sem copiar ou compartilhar referências.

    • 21:08 - Contagem de referências
    • No exemplo de otimização do app, é usado o novo tipo 'Span' para melhorar o desempenho e aumentar a segurança da memória. No Instruments, o gráfico de chamas é usado na análise do Time Profiler. A criação de perfis de dados foca o 'QOIParser' e revela que parte do tempo é gasta em operações de contagem de referências no tipo 'Data', devido à sua semântica de copy-on-write. 'Span' e seus tipos relacionados são uma nova forma de trabalhar com memória contígua em uma coleção. Eles usam o recurso não escapável ('~Escapable') do Swift, que vincula o tempo de vida à coleção, garantindo segurança de memória e eliminando a necessidade de gerenciamento manual. Isso permite o acesso eficiente à memória sem os riscos associados a ponteiros não seguros. O exemplo demonstra como usar os tipos 'Span' para reescrever métodos existentes, tornando-os mais simples, seguros e eficientes. Nos métodos de análise de imagem, 'Data' é substituído por 'RawSpan', reduzindo a sobrecarga da contagem de referências. Além disso, o 'OutputSpan' é adotado no processo de análise para otimização adicional, tornando a operação seis vezes mais rápida, sem recorrer a ponteiros não seguros.

    • 29:52 - Biblioteca de análise binária do Swift
    • O Swift Binary Parsing permite criar parsers seguros e eficientes para formatos binários. Ele oferece ferramentas para lidar com aspectos de segurança, incluindo prevenção de estouro de inteiros, especificação de sinalização, largura de bits e ordem dos bytes. A biblioteca já é usada pela Apple e está disponível para você experimentar e contribuir por meio dos fóruns Swift e do GitHub.

    • 31:03 - Próximas etapas
    • Os principais pontos incluem: Uso do Xcode e Instruments para analisar o desempenho de apps. Análise do desempenho de algoritmos para identificar gargalos. Exploração de soluções para os problemas acima com os novos tipos 'InlineArray' e 'Span' lançados no Swift 6.2.

Developer Footer

  • Vídeos
  • WWDC25
  • Melhore o uso da memória e o desempenho com o 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