Creación de perfiles con instrumentos

En el equipo de soporte empresarial, vemos muchos proyectos de iOS. En algún momento, en cualquier desarrollo de iOS, los desarrolladores a menudo terminan ejecutando su juego y se quedan pensando "¿Por qué diablos se ejecuta tan lento?". Existen excelentes conjuntos de herramientas para analizar el rendimiento y uno de los mejores es Instruments. ¡Siga leyendo para descubrir cómo usarlo para encontrar sus problemas!
Para usar Instrumentos, o cualquiera de las herramientas de depuración de XCode, necesitarás construir un proyecto de Unity para el objetivo de compilación de iOS (con las opciones de compilación de desarrollo y depuración de scripts desmarcadas). Luego necesitarás compilar el proyecto XCode resultante con XCode en modo Release e implementarlo en un dispositivo iOS conectado.
Después de iniciar Instrumentos (ya sea presionando prolongadamente el botón de reproducción o seleccionando Productos>Perfil), seleccione Perfilador de tiempo. Para iniciar una ejecución de creación de perfiles, seleccione la aplicación creada en el selector de aplicaciones y luego presione el botón rojo Grabar. La aplicación se iniciará en el dispositivo iOS con los instrumentos conectados y el Time Profiler comenzará a registrar la telemetría. La telemetría aparecerá como un gráfico azul en la línea de tiempo de Instrumentos.

Nota: Para limpiar la jerarquía de llamadas, presione el botón Árbol de llamadas en la parte inferior izquierda del panel Detalles para mostrar las opciones y seleccionar Aplanar recursión y Ocultar bibliotecas del sistema.

Aparecerá una lista de llamadas a métodos en la sección de detalles de la ventana Instrumentos. Cada llamada a un método de nivel superior representa un hilo dentro de la aplicación.
En general, el método principal es la ubicación de todos los puntos de interés, ya que contiene todo el código administrado.
Expandir el método principal producirá un árbol profundo de llamadas a métodos. La rama principal está entre dos métodos:
- [startUnity] y UnityLoadApplication (los nombres de estos métodos a veces aparecen en MAYÚSCULAS).
- PlayerLoop
[startUnity] es de interés ya que contiene todo el tiempo dedicado a inicializar el motor Unity. Debajo de él se encontrará un método llamado UnityLoadApplication. Es debajo de UnityLoadApplication donde se puede perfilar el tiempo de inicio.

Una vez que haya perfilado un buen segmento de tiempo de su aplicación, pause el generador de perfiles y comience a expandir el árbol. A medida que avanza por el árbol, notará que el tiempo en ms se reduce en la columna de la izquierda. Lo que usted busca son artículos que provoquen una reducción significativa del tiempo. Este será un punto de gran rendimiento. Una vez que hayas encontrado uno, puedes regresar a tu base de código y descubrir qué diablos está pasando que está tomando tanto tiempo. Podría ser que sea una operación totalmente necesaria, o podría ser que en algún momento del pasado distante hayas pirateado algún código de preproducción que haya llegado a tu proyecto de producción, o... bueno... podría haber un millón de razones en realidad. Si decides solucionar este problema o no, o cómo lo hagas, dependerá en gran medida de ti, ya que conoces tu código base mejor que nadie. :D
Los instrumentos también se pueden utilizar para buscar sumideros de rendimiento que estén ampliamente distribuidos (aquellos que carecen de un único gran punto crítico, sino que aparecen como unos pocos milisegundos de tiempo perdido en muchos lugares diferentes de una base de código). Para hacer esto, escriba un nombre de función parcial o completo en el cuadro de búsqueda de símbolos de Instrumentos, que se muestra al presionar ⌘F o hacer clic en Buscar/Buscar… en el menú Editar . Si está perfilando una parte del juego, expanda PlayerLoop y contraiga todos los métodos debajo de él. Si desea perfilar el tiempo de inicio, expanda UnityLoadApplication y contraiga los métodos debajo de él. La cantidad total de milisegundos desperdiciados en una operación específica se puede estimar aproximadamente observando el tiempo total empleado en PlayerLoop o UnityLoadApplication y restando la cantidad de milisegundos ubicada en la columna propia.
Métodos comunes de búsqueda:
- “Box(“, “box” y “box” — estos indican que se está produciendo un boxing de valores de C#; la mayoría de los casos de boxing se solucionan de manera trivial
- “Concat”: la concatenación de cadenas suele optimizarse fácilmente
- “CreateScriptingArray”: todas las API de Unity que devuelven matrices asignarán nuevas copias de matrices. Minimizar las llamadas a estos métodos.
- “Reflexión”: la reflexión es lenta. Utilice esto para estimar el tiempo perdido en la reflexión y eliminarlo cuando sea posible.
- “FindObjectOfType”: use esto para localizar llamadas repetidas o innecesarias a FindObjectOfType u otras API de Unity conocidas como lentas.
- “Linq”: examine el tiempo que se pierde al crear y descartar consultas Linq; considere reemplazar los puntos críticos con métodos optimizados manualmente.
Además de perfilar el tiempo de la CPU, Instruments también permite perfilar el uso de la memoria. El generador de perfiles de asignaciones de instrumentos proporciona dos sondas que ofrecen vistas detalladas del uso de memoria de una aplicación. La sonda de asignaciones permite la inspección de los objetos residentes en la memoria durante un período de tiempo específico. La sonda VM Tracker permite monitorear el tamaño del montón de memoria sucia, que es la métrica principal utilizada por iOS para determinar cuándo se debe cerrar una aplicación de manera forzosa.
Ambas sondas se ejecutarán simultáneamente al seleccionar el perfilador de asignaciones en Instrumentos. Como de costumbre, comience la ejecución del perfil presionando el botón rojo Grabar.
Para configurar correctamente la sonda de asignaciones, asegúrese de que las siguientes configuraciones sean correctas. En la parte inferior de la ventana, asegúrese de que la duración de la asignación (opción del medio) esté configurada en Creado y persistente. En las Opciones de grabación (menú Archivo), asegúrese de que la opción Descartar eventos para la memoria liberada esté marcada.
La pantalla más útil para examinar el comportamiento de la memoria es la pantalla Estadísticas, que es la pantalla predeterminada cuando se utiliza la sonda Asignaciones. Esta pantalla muestra una línea de tiempo. Cuando se utiliza con la configuración recomendada, el gráfico muestra líneas azules que indican el tiempo y la magnitud de las asignaciones de memoria que aún están activas. Al observar este gráfico, puede detectar memoria de larga duración o filtrada simplemente repitiendo el escenario bajo prueba y asegurándose de que no queden líneas azules activas entre ejecuciones.
Otra visualización útil es la visualización de árboles de llamadas. Muestra la línea de código en la que se realizan las asignaciones, junto con la cantidad de consumo de memoria del que es responsable la línea de código. Puede cambiar la visualización haciendo clic a la derecha de Detalles, como se muestra aquí:

A continuación se puede ver que aproximadamente el 25% del uso total de memoria de la aplicación bajo prueba se debe únicamente a los sombreadores. Dada la ubicación de los sombreadores en el hilo de carga, estos deben ser los sombreadores estándar incluidos en los proyectos Unity predeterminados que luego se cargan en el momento de inicio de la aplicación.

Como antes, una vez que haya identificado un punto de acceso, lo que haga con él dependerá totalmente de su proyecto.
Así que ahí lo tienes. Una breve guía de instrumentos. 1000 (aproximadamente) palabras y ninguna referencia al Equipo A. No queremos meternos en problemas como la última vez. Las violaciones de derechos de autor oficialmente no son divertidas™.
El equipo de soporte empresarial está creando más de estas guías y publicaremos las versiones completas de nuestras guías de mejores prácticas en los próximos meses.
Nos encanta cuando un plan sale adelante.
