iOS-Trace: Optimización Autónoma del Rendimiento de Aplicaciones
iOS-Trace es un motor de optimización de rendimiento en bucle cerrado para aplicaciones iOS y iPadOS que se ejecutan en dispositivos iPhone/iPad físicos y simuladores de iOS locales (SwiftUI, UIKit, Metal, CoreAudio / AVAudioEngine y redes URLSession).
El objetivo principal es eliminar la interacción manual con la GUI de Instruments. Un agente de IA puede diagnosticar de forma autónoma, localizar cuellos de botella, implementar cambios de código, re-probar con evaluación comparativa diferencial e iterar hasta que los objetivos de rendimiento se verifiquen con datos empíricos.
+-------------------------------------------------------------------------+
| El Bucle de Optimización Autónoma |
| |
| 1. Alineación de Objetivos ──> 2. Traza de Diagnóstico ──> 3. Corrección de Código |
| ^ │ |
| │ ▼ |
| └────── Iterar si no se cumple el objetivo <── 4. Verificación de Re-prueba |
+-------------------------------------------------------------------------+
Fase 1: Alineación de Objetivos del Usuario (Cuestionario Previo al Vuelo)
Antes de modificar el código o recopilar trazas en dispositivos móviles, el agente debe alinearse con el usuario sobre los objetivos de optimización y los criterios de éxito.
Herramienta Modal vs Interacción por Chat
- Si su plataforma de agente proporciona una herramienta de cuestionario/modal interactiva (por ejemplo,
ask_question, diálogos de entrada o listas de opciones seleccionables), invóquela para presentar estas opciones de forma limpia al usuario. - Si no hay una herramienta modal disponible, pregunte al usuario directamente en la conversación con opciones estructuradas y valores recomendados concretos.
Preguntas para Hacer al Usuario
-
Objetivo Principal de Optimización:
- Opción A: Reducir el consumo de batería, la utilización de la CPU y la limitación térmica.
- Opción B: Reducir la huella de memoria, los picos de asignación transitorios o prevenir bloqueos por Jetsam OOM.
- Opción C: Eliminar el tartamudeo de los fotogramas de la interfaz de usuario y los fotogramas de animación caídos (ProMotion 120Hz Hitches).
- Opción D: Acelerar el tiempo de lanzamiento en frío de la aplicación móvil.
- Opción E: Optimizar la sobrecarga de la radio de red y la eficiencia de las solicitudes por lotes.
-
Objetivos de Rendimiento Específicos (Proporcionar Valores Predeterminados Recomendados):
- Objetivos de Batería y CPU:
- Objetivo de Línea Base en Reposo: < 15 M/s de instrucciones, Impacto de CPU < 0,3.
- Objetivo de Carga de Trabajo Activa: < 80 M/s de instrucciones (o especificar: reducir entre un 30% y un 50%).
- Objetivos de Memoria y Jetsam:
- RAM Residente Máxima: Limitar a < 150 MB (utilidades estándar) o < 300 MB (aplicaciones multimedia/interactivas enriquecidas).
- Tasa de Eventos de Asignación: < 400 eventos/seg durante la interacción en estado estable.
- Fugas de Memoria: Exactamente 0 fugas persistentes.
- Objetivos de Suavidad de la IU y Velocidad de Fotogramas:
- Relación de Tirones (Hitch Ratio): < 5,0 ms/s (aceptable), < 1,0 ms/s (fluido / grado ProMotion 120Hz).
- Duración Máxima del Tirón: < 16,6 ms (60 Hz) o < 8,33 ms (120 Hz).
- Objetivos de Tiempo de Lanzamiento:
- Tiempo hasta el Primer Fotograma: < 400 ms (excelente), < 800 ms (aceptable).
- Objetivos de Red y Radio:
- Sobrecarga de Radio: Agrupar pings periódicos en solicitudes ráfaga única para evitar la energía de espera de la cola de radio.
- Objetivos de Batería y CPU:
-
Escenario de Evaluación Comparativa del Usuario:
- Pregunte al usuario qué pantalla específica, interacción de usuario, dispositivo físico o simulador desea evaluar.
Una vez que se confirmen los objetivos, proceda a la Fase 2.
Alcance y Requisitos Previos
- Plataformas objetivo: Aplicaciones iOS y iPadOS que se ejecutan en dispositivos iPhone/iPad físicos conectados por USB o red local, o simuladores de iOS locales. (Para aplicaciones de escritorio macOS, use macOS-Trace).
- Sistema host: macOS 12+ ejecutándose en Apple Silicon o Mac Intel con Xcode completo o Herramientas de Línea de Comandos de Xcode (
xcode-select -p,xcrun xctrace version). - Preparación del dispositivo:
- El iPhone/iPad físico debe estar desbloqueado y ser de confianza para el Mac host.
- El dispositivo debe aparecer bajo
== Devices ==(no== Devices Offline ==) al ejecutarxcrun xctrace list devices. - El bloqueo automático debe configurarse en "Nunca" o la pantalla debe mantenerse activa durante las grabaciones para evitar que iOS suspenda los procesos en segundo plano.
- Python: Python 3.8+ en el Mac host (usa solo la biblioteca estándar; cero dependencias pip externas).
- Permisos de proceso: Se requieren compilaciones de depuración o compilaciones aprovisionadas para desarrolladores con el permiso
get-task-allowpara--attach <PID>.
Reglas para Agentes
Siga estas reglas no negociables durante la creación de perfiles automatizada:
- Verificar el estado de conexión del dispositivo: Ejecute siempre
xcrun xctrace list devicesantes de grabar. Nunca intente grabar contra un dispositivo listado bajo== Devices Offline ==. - Evitar el bloqueo de pantalla y la ejecución en segundo plano: Si el dispositivo iOS se bloquea o vuelve a la pantalla de inicio, iOS suspende o limita el proceso, produciendo mediciones no válidas. Mantenga el dispositivo despierto y la aplicación en primer plano.
- Establecer primero una línea base: Nunca grabe solo la carga de trabajo activa. Capture siempre una ejecución de línea base en reposo (aplicación en primer plano, pantalla del dispositivo encendida, carga de trabajo en pausa) antes de grabar el estado activo. Calcule:
Delta = Activo - Línea base. - Usar parámetros de prueba iguales: Compare ejecuciones con duraciones de muestra idénticas (predeterminado:
60s), estados de batería del dispositivo idénticos (evite la creación de perfiles con menos del 20% de batería o en modo de bajo consumo) y datos de entrada de prueba idénticos. - Sin dependencias de Python de terceros: Todos los scripts incluidos (
scripts/compare_elements.py,scripts/parse_power.py,scripts/top_categories.py) usan solo la biblioteca estándar de Python 3. - Guardar salidas en
/tmp/ios-traces/: Almacene todos los paquetes.tracey exportaciones.xmlen/tmp/ios-traces/con nombres de archivo con marca de tiempo y etiqueta de escenario. - Proteger el presupuesto de contexto de la conversación: Los archivos de traza y los documentos XML exportados sin procesar pueden tener decenas o cientos de megabytes. Nunca vuelque salidas
.tracesin procesar, árboles de llamadas completos o XML de asignaciones no analizados en el contexto de conversación del agente. Utilice siempre los scripts de Python incluidos para transmitir, filtrar, clasificar y resumir los datos antes de leerlos. - Centrarse en los cuellos de botella principales: No distribuya micro-optimizaciones en docenas de funciones de utilidad inocentes. Primero, cree un perfil para confirmar el contribuyente dominante (por ejemplo, instancias de superficie redundantes, re-evaluaciones de temporizadores de alta frecuencia, E/S sin búfer) y centre los esfuerzos de optimización exclusivamente en esa causa raíz.
- Nunca altere silenciosamente la interfaz de usuario, los efectos visuales o el comportamiento principal: Si un cuello de botella de rendimiento implica fidelidad visual (como desenfoque/materials, animaciones de fotogramas, sombras, transiciones de diseño) o comportamiento esencial del software:
- No elimine ni degrade unilateralmente la característica visual.
- Pida permiso formalmente al usuario primero (usando un mensaje interactivo o un mensaje de chat explícito).
- Articule claramente la compensación: Describa el cambio visual antes y después, explique por qué la característica consume recursos y presente la ganancia de rendimiento concreta esperada (por ejemplo, "Deshabilitar la sombra dinámica y el desenfoque en las vistas de tarjeta reducirá el impacto promedio de la GPU de 1,8 a 0,2 y eliminará los tirones de ProMotion 120Hz").
- Limpiar los artefactos de grabación: Cada grabación de
xctraceescribe trazas de kernel transitorias de varios GB (instruments*.ktrace) y un caché de la CLI de Instruments (C/com.apple.dt.InstrumentsCLI) en la carpeta temporal del sistema por usuario ($TMPDIR).scripts/run_trace.shlos elimina automáticamente al salir (tanto en caso de éxito como de fallo). Cuando ejecutexctracedirectamente, límpielos usted mismo antes de concluir:Nunca termine una sesión dejando cientos de GB de datos de grabación transitorios.find "${TMPDIR:-/tmp}" -maxdepth 1 -type f -name 'instruments*.ktrace' -delete 2>/dev/null || true
El Protocolo de Optimización de 4 Fases
Fase 2: Perfilado de Diagnóstico y Atribución
Antes de escribir código, mida el estado actual en el dispositivo y aísle la causa raíz:
# 1. Confirmar que el dispositivo objetivo está en línea y desbloqueado (verificación opcional;
# run_trace.sh detecta automáticamente el primer iPhone/iPad conectado cuando se omite --device)
xcrun xctrace list devices
BUNDLE_ID="com.example.MyApp"
# SKILL_DIR = directorio de instalación de esta habilidad (ajuste si está instalado en otro lugar)
SKILL_DIR="$HOME/.claude/skills/ios-trace"
# 2. Grabar línea base en reposo de 60s (dispositivo desbloqueado, aplicación en primer plano, carga de trabajo en pausa)
"$SKILL_DIR/scripts/run_trace.sh" \
--bundle-id "$BUNDLE_ID" \
--template power \
--duration 60s \
--label "01-baseline"
# 3. Activar la carga de trabajo objetivo en la aplicación, grabar estado activo
"$SKILL_DIR/scripts/run_trace.sh" \
--process "MyApp" \
--template power \
--duration 60s \
--label "02-pre-opt"
# 4. Calcular delta previo a la optimización
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/ios-traces/01-baseline-power.xml:"Línea Base en Reposo" \
/tmp/ios-traces/02-pre-opt-power.xml:"Activo Pre-Opt"
Use las plantillas especializadas para atribuir el cuello de botella:
- Ejecute
--template timepara aislar las funciones activas del árbol de llamadas en los hilos de trabajo. - Ejecute
--template allocconscripts/top_categories.pypara identificar las asignaciones excesivas que causan presión de memoria. - Ejecute
--template hitchesdurante el desplazamiento para aislar los retrasos de renderizado frente a los de confirmación en pantallas ProMotion. - Ejecute
--template networkpara detectar activaciones de radio continuas no agrupadas.
Fase 3: Modificación de Código Dirigida
Aplique correcciones mínimas y quirúrgicas basadas en los hallazgos:
- Picos de Memoria y Jetsam: Adoptar la reducción de resolución para imágenes de alta resolución con
CGImageSourceCreateThumbnailAtIndexen lugar de cargarUIImagede tamaño completo. - Tirones de ProMotion: Eliminar sombras complejas y pases de mezcla fuera de pantalla; descargar los cálculos de diseño de vistas pesadas del hilo principal.
- Sobrecarga de Energía de Radio: Agrupar las solicitudes de red periódicas en ráfagas de carga útil unificadas para eliminar la energía de espera de la cola de radio.
- Audio en Tiempo Real: Asegurar cero asignaciones de montón en las devoluciones de llamada de renderizado de CoreAudio (
AVAudioEngineo RemoteIO).
Recompile la aplicación e impleméntela en el dispositivo.
Fase 4: Re-prueba, Revisión Cuantitativa y Puerta de Decisión
Vuelva a ejecutar el perfil en condiciones idénticas y evalúe el delta:
# 1. Grabar carga de trabajo activa posterior a la optimización
"$SKILL_DIR/scripts/run_trace.sh" \
--process "MyApp" \
--template power \
--duration 60s \
--label "03-post-opt"
# 2. Comparar Pre-Opt vs Post-Opt con respecto a la Línea Base
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/ios-traces/01-baseline-power.xml:"Línea Base en Reposo" \
/tmp/ios-traces/02-pre-opt-power.xml:"Activo Pre-Opt" \
/tmp/ios-traces/03-post-opt-power.xml:"Activo Post-Opt"
Ejemplo de Salida de Decisión:
Escenario Seg CPU Prom CPU Máx Display GPU Prom Instr Tot Instr M/s WiFi Tx/Rx
=========================================================================================================
Línea Base en Reposo 60 0,12 0,60 0,05 0,00 0,85G 14,2 0,0/0,0MB
Activo Pre-Opt 60 2,40 4,80 1,10 1,80 15,60G 260,0 14,2/1,8MB
Activo Post-Opt 60 0,55 1,10 0,15 0,20 4,20G 70,0 2,1/0,4MB
---------------------------------------------------------------------------------------------------------
Diferencial vs Línea Base [Línea Base en Reposo]:
Activo Pre-Opt +245,8 M/s instrucciones, Delta CPU Prom +2,28, Delta WiFi Tx +14,20MB
Activo Post-Opt +55,8 M/s instrucciones, Delta CPU Prom +0,43, Delta WiFi Tx +2,10MB
Delta de Optimización (Post-Opt vs Pre-Opt):
Rendimiento de instrucciones: -73,1% (70,0 vs 260,0 M/s)
Impacto Promedio de CPU: -77,1% (0,55 vs 2,40)
Impacto Promedio de GPU: -88,9% (0,20 vs 1,80)
Tráfico de Radio WiFi: -85,2% (2,1MB vs 14,2MB)
Lógica de la Puerta de Decisión:
- Objetivo Alcanzado: Presente la tabla de comparación empírica al usuario y concluya.
- Objetivo No Alcanzado: Mantenga la optimización anterior, aísle el siguiente punto crítico restante y repita la Fase 3 y la Fase 4.
Limpieza Posterior al Informe: Después de que el usuario acepte el informe de optimización final, elimine los paquetes .trace acumulados en /tmp/ios-traces/ (cada uno puede tener decenas de GB) a menos que el usuario solicite explícitamente conservarlos. La tabla de comparación finalizada y las exportaciones .xml mostradas en el informe son evidencia suficiente.
Comandos CLI Directos
Si ejecuta xctrace directamente sin run_trace.sh:
Grabar
# Adjuntar a la aplicación en ejecución en el dispositivo
xcrun xctrace record \
--device <DEVICE_UDID> \
--template 'Power Profiler' \
--time-limit 60s \
--output /tmp/ios-traces/power.trace \
--attach <PID>
# Iniciar en frío la aplicación en el dispositivo
xcrun xctrace record \
--device <DEVICE_UDID> \
--template 'Time Profiler' \
--time-limit 30s \
--output /tmp/ios-traces/launch.trace \
--launch -- com.example.MyApp <LaunchArgs>
Exportar
# Exportar tabla de Impacto de Energía (instrucciones de CPU, energía, GPU, Pantalla, WiFi/Celular)
xcrun xctrace export \
--input /tmp/ios-traces/power.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='ProcessSubsystemPowerImpact']" \
> /tmp/ios-traces/power.xml
# Exportar tabla de resumen de Asignaciones
xcrun xctrace export \
--input /tmp/ios-traces/alloc.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='all-allocations-summary']" \
> /tmp/ios-traces/alloc.xml
Referencia de Plantillas
Plantillas de Instruments compatibles con iOS a través de scripts/run_trace.sh y xctrace sin interfaz gráfica:
Cómputo, Batería y Energía
| Plantilla | Nombre Corto | Métricas Objetivo y Esquema de Exportación | Caso de Uso |
|---|---|---|---|
Power Profiler | power | Instrucciones/seg (M/s), impactos de energía de CPU/GPU/Pantalla/WiFi/Celular (ProcessSubsystemPowerImpact). | Agotamiento integral de la batería, limitación térmica y evaluación comparativa A/B. |
Time Profiler | time | Pesos de muestras de CPU por hilo, puntos críticos del árbol de llamadas, métodos de bloqueo del hilo principal. | Alta utilización de la CPU, hilos de trabajo descontrolados y rutas de función activas. |
CPU Counters | c | Recuentos de instrucciones, fallos de caché, tasa de bifurcaciones erróneas, eficiencia de la tubería. | Optimización profundamente técnica a nivel de microarquitectura. |
Metal System Trace | metal | Tiempos de GPU, límite de sombreado, asignaciones de búfer, cuellos de botella de canalización de renderizado. | Aplicaciones de juegos, AR y gráficos 3D. |
Gestión de Memoria
| Plantilla | Nombre Corto | Métricas Objetivo y Esquema de Exportación | Caso de Uso |
|---|---|---|---|
Allocations | alloc | Recuento de asignaciones activas, tasa de asignación, memoria residente (all-allocations-summary). | Fugas de memoria, presión Jetsam, asignación excesiva de objetos temporales. |
Leaks | leaks | Diagnóstico de fugas de memoria, detección de memoria huérfana. | Fugas de objetos, contenedores de retención cíclica. |
VM Tracker | vm | Páginas capturadas, memoria virtual residente, tamaño de región. | Carga de imágenes de alta resolución, memoria compartida, archivos mapeados en memoria. |
Interfaz de Usuario y Gráficos
| Plantilla | Nombre Corto | Métricas Objetivo y Esquema de Exportación | Caso de Uso |
|---|---|---|---|
Hitches (Objective-C) | hitches-objc | Relación de tirones, duración máxima del tirón (hitches con métodos Objective-C). | Animaciones UIKit, desplazamiento de vista de tabla/colección. |
Hitches (Swift) | hitches-swift | Relación de tirones, duración máxima del tirón (hitches con métodos Swift). | Animaciones SwiftUI, diseño sin conexión. |
Core Animation | ca | Tasa de fotogramas de renderizado, tiempo de compromiso, tiempo de renderizado. | Desenfoque excesivo, sombras, pases de mezcla fuera de pantalla. |
Metal GPU Trace | gpu | Tiempo de GPU, uso de la memoria de la GPU, ancho de banda de textura. | Canalización de renderizado personalizada. |
Red y Conectividad
| Plantilla | Nombre Corto | Métricas Objetivo y Esquema de Exportación | Caso de Uso |
|---|---|---|---|
Network | network | Bytes de carga/descarga de WiFi y Celular, tiempo de cola de radio activo, intervalos entre ráfagas. | Patrones de sondeo de alta frecuencia, modo de espera de radio. |
Connections | connections | Recuento de conexiones, duración de TCP, activación de DNS. | Agrupación de conexiones, conexiones de base de datos. |
Audio
| Plantilla | Nombre Corto | Métricas Objetivo y Esquema de Exportación | Caso de Uso |
|---|---|---|---|
Audio | audio | Latencia de audio, fallos del búfer, sobrecarga de procesamiento. | AVAudioEngine, RemoteIO, audio en tiempo real en CoreAudio. |
Lanzamiento e Inicialización
| Plantilla | Nombre Corto | Métricas Objetivo y Esquema de Exportación | Caso de Uso |
|---|---|---|---|
App Launch | launch | Tiempo hasta el primer fotograma, duración de la inicialización de dyld, tiempo de pre-main. | Tiempo de lanzamiento en frío de la aplicación. |
Scripts Incluidos
Todos los scripts están en scripts/ dentro de este directorio de habilidad. Usan solo la biblioteca estándar de Python 3.
run_trace.sh
Script de shell para envoltorio de grabación que gestiona la detección de dispositivos, el mantenimiento de la pantalla activa, el manejo de errores, la exportación automática de XML y la limpieza de archivos de traza transitorios del kernel.
# Uso
"$SKILL_DIR/scripts/run_trace.sh" --bundle-id "com.example.MyApp" --template power --duration 60s --label "my-scenario"
compare_elements.py
Combina múltiples exportaciones XML de Power Profiler en una tabla resumen con una fila por ejecución, calcula deltas diferenciales con respecto a la línea base y muestra estadísticas resumidas de ganancia de optimización.
parse_power.py
Exporta el impacto de subsistemas individuales desde un exporte XML de Power Profiler de una sola ejecución, como entrada para compare_elements.py.
top_categories.py
Analiza un exporte XML de Allocations, ordena por recuento de asignaciones y bytes asignados, e imprime las 20 categorías principales. Utilice después de run_trace.sh --template alloc.
Notas de Implementación para Desarrolladores de Agentes
SKILL_DIRdebe resolverse relativo a la ubicación de instalación de la habilidad. El fragmento de código de ejemplo anterior usa$HOME/.claude/skills/ios-trace, pero los agentes deben consultar su propia ruta de instalación.- El agente debe solicitar al usuario el
BUNDLE_ID, el nombre del proceso, la plantilla y la duración de la grabación al comienzo de la Fase 1. - Los archivos de traza grandes (>1 GB) son comunes. Nunca lea paquetes
.tracesin procesar en el contexto de la conversación; utilicecompare_elements.pyytop_categories.pypara extraer un resumen de nivel de tabla. Si se necesita un análisis de árbol de llamadas, extraiga las 10-20 funciones principales de muestra de la exportación XML. - La decisión de iterar de nuevo (Fase 3 y Fase 4) o detenerse recae en el agente basándose en los umbrales configurados por el usuario en la Fase 1. Si el umbral de rendimiento se cumple o supera, presente el informe y limpie. Si no se cumple, repita Fase 2 (con una nueva perspectiva de diagnóstico) y Fase 3.
Referencias y Recursos
- macOS-Trace: Optimización de rendimiento autónoma para aplicaciones macOS de escritorio. Repositorio: https://github.com/kmgcc/macOS-Trace
- Documentación de Instruments: https://developer.apple.com/documentation/xcode/instruments
- Referencia de xctrace: https://developer.apple.com/documentation/xcode/exporting-and-importing-instruments-data