Compartir a través de


Mecanismos de compilación de iOS

En esta guía se examina cómo medir el tiempo de las aplicaciones y cómo usar métodos que se pueden emplear para compilaciones rápidas en todas las configuraciones de compilación.

El desarrollo de grandes aplicaciones conlleva mucho más que simplemente escribir código que funcione. Una aplicación bien escrita debe contener optimizaciones que realicen compilaciones más rápido con aplicaciones que son más pequeñas y que se ejecutan más rápido. Estas optimizaciones no solo mejorarán la experiencia del usuario, sino también la de usted o la de cualquier desarrollador que trabaje en el proyecto. Es fundamental asegurarse de que al trabajar con la aplicación todo se organiza con frecuencia.

Recuerde que las opciones predeterminadas son seguras y rápidas, pero que no son óptimas para cualquier situación. Además, muchas opciones pueden ralentizar o acelerar el ciclo de desarrollo en función de cada proyecto. Por ejemplo, la eliminación nativa lleva tiempo, pero si se gana muy poco, entonces el tiempo empleado para la eliminación no se recuperará con una implementación más rápida. Por otra parte, la eliminación nativa puede reducir la aplicación significativamente, en cuyo caso se implementará más rápido. Esto varía entre los proyectos, y la única forma de saberlo es probar.

Las velocidades de compilación de Xamarin también pueden verse afectadas por distintas funcionalidades y capacidades de un equipo que pueden mermar el rendimiento: funcionalidades del procesador, velocidades del bus, cantidad de memoria física, velocidad del disco y velocidad de la red. Estas limitaciones de rendimiento van más allá del ámbito de este documento y son responsabilidad del desarrollador.

Aplicaciones de control de tiempo

Para habilitar el resultado de diagnóstico de MSBuild en Visual Studio para Mac:

  1. Haga clic en Visual Studio para Mac > Preferencias...
  2. En la vista de árbol de la izquierda, seleccione Proyectos > Compilar
  3. En el panel de la derecha, establezca el menú desplegable del contenido de registro en Diagnóstico: Setting the Log verbosity
  4. Haga clic en Aceptar
  5. Reinicie Visual Studio para Mac.
  6. Limpie y recompile el paquete.
  7. Vea los resultados de diagnóstico en el panel de errores (Ver > Paneles > Errores); para ello, haga clic en el botón Salida de la compilación

Control de tiempo de mtouch

Para mostrar información específica del proceso de compilación de mtouch, pase --time --time a los argumentos mtouch en Opciones del proyecto. Los resultados se encuentran en la salida de compilación, mediante la búsqueda de la tarea MTouch:

Setup: 36 ms
Resolve References: 982 ms
Extracted native link info: 987 ms
...
Total time: 1554 ms

Conectarse desde Visual Studio con el host de compilación

Las herramientas de Xamarin técnicamente funcionan en cualquier equipo Mac que pueda ejecutar OS X 10.10 Yosemite o posterior. Sin embargo, el rendimiento del equipo Mac puede afectar a las experiencias de desarrollador y a los tiempos de compilación.

En el estado desconectado, Visual Studio en Windows solo realiza la fase de compilación de C# y no intenta realizar la vinculación o compilación AOT, empaquetar la aplicación en un lote .app o firmar el lote de aplicaciones. (La fase de compilación de C# no suele crear cuellos de botella de rendimiento). Intente identificar en qué parte de la canalización la compilación se está ralentizando; para ello, compile directamente en el host de compilación de Mac en Visual Studio para Mac.

Además, uno de los puntos más comunes en los que se produce lentitud es la conexión de red entre el equipo Windows y el host de compilación de Mac. Esto puede deberse a un obstáculo físico en la red, cuando se usa una conexión inalámbrica o si hay que recorrer un equipo saturado (como un servicio en la nube en Mac).

Trucos del simulador

Al desarrollar aplicaciones para dispositivos móviles, es esencial implementar rápidamente el código. Por distintos motivos, incluidos los requisitos de velocidad y la falta de aprovisionamiento de dispositivos, los desarrolladores suelen implementar en un emulador o simulador instalado previamente. Para los fabricantes de herramientas de desarrollo, la decisión de proporcionar un simulador o emulador se basa en el equilibrio entre la velocidad y la compatibilidad.

Apple proporciona un simulador para el desarrollo en iOS, que impulsa la velocidad en relación con la compatibilidad con la creación de un entorno menos restrictivo para la ejecución de código. Este entorno menos restrictivo permite a Xamarin usar el compilador Just-In-Time (JIT) para el simulador (en contraposición a AOT en un dispositivo), lo que significa que la compilación se realiza con código nativo en tiempo de ejecución. Como Mac es mucho más rápido que un dispositivo, permite mejorar el rendimiento.

El simulador usa un iniciador de aplicaciones compartido, lo que permite la reutilización del iniciador, en lugar de tener que compilarlo en cada ocasión, según se requiera en el dispositivo.

Teniendo en cuenta la información anterior, en la lista siguiente se proporciona alguna información sobre los pasos que hay que seguir para compilar e implementar la aplicación en el simulador a fin mejorar el rendimiento.

Sugerencias

  • Para compilaciones:
    • Anule la selección de la opción Optimizar imágenes PNG en Opciones del proyecto. Esta optimización no es necesaria para las compilaciones en el simulador.
    • Establezca el enlazador en No vincular. Deshabilitar el enlazador es más rápido, porque ejecutarlo supone una gran cantidad de tiempo.
    • Deshabilitar el iniciador de aplicaciones compartido con la marca --nofastsim conlleva que las compilaciones del simulador sean mucho más lentas. Quite esta marca cuando ya no sea necesaria.
    • El uso de las bibliotecas nativas es más lento, porque el ejecutable principal de simlauncher compartido no puede reutilizarse en tales casos, y es necesario compilar un ejecutable específico por aplicación en cada compilación.
  • Para implementación
    • Si es posible, mantenga siempre en ejecución el simulador. El simulador puede tardar hasta doce segundos en arrancar el simulador en frío.
  • Consejos adicionales
    • Es mejor usar la compilación que la recompilación, ya que esta última realiza una limpieza antes de la compilación. La limpieza puede tardar mucho tiempo, ya que elimina referencias que podrían usarse.
    • Benefíciese del hecho de que el simulador no fuerza el espacio aislado. Tener recursos grandes, como vídeos u otros recursos, incluidos en el proyecto puede generar operaciones de copia de archivos costosas cada vez que la aplicación se inicia en el simulador. Evite estas operaciones costosas colocando estos archivos en el directorio principal y haga referencia a ellos en la aplicación mediante la ruta de acceso del archivo completa.
    • En caso de duda, use la marca --time --time para medir el cambio.

En la captura de pantalla siguiente se ilustra cómo establecer estas opciones para el simulador en las opciones de iOS:

Screenshot shows Project Options, including Linker behavior, Additional mtouch arguments, and Optimize P N G images.

Trucos de dispositivos

La implementación en el dispositivo es similar a la implementación en el simulador, ya que el simulador es un subconjunto pequeño de la compilación utilizada para el dispositivo iOS. La compilación en el dispositivo requiere muchos más pasos, pero tiene la ventaja de ofrecer oportunidades adicionales para optimizar la aplicación.

Configuraciones de compilación

Se proporciona una serie de configuraciones de compilación para implementar aplicaciones iOS. Es importante tener un buen conocimiento de cada configuración, para saber cuándo y por qué debe optimizarse.

  • Depuración
    • Esta es la configuración principal que debe usarse mientras una aplicación está en fase de desarrollo y, por tanto, debe realizarse lo más rápido posible.
  • Release
    • Las compilaciones de versiones son las que se proporcionan a los usuarios, y es fundamental centrar la atención en el rendimiento. Cuando se usa la configuración de versiones, puede usar el compilador de optimización LLVM y optimizar los archivos PNG.

También es importante entender la relación entre la compilación y la implementación. El tiempo de implementación es una función del tamaño de la aplicación. Una aplicación más grande tarda más tiempo en implementarse. Al reducir el tamaño de la aplicación, puede reducir el tiempo de implementación.

Minimizar el tamaño de la aplicación también puede reducir el tiempo de compilación. Esto se debe a que quitar código de la aplicación lleva menos tiempo que compilar de forma nativa el código que no se usará. Los archivos objeto más pequeños tardan menos en vincularse, por lo que se crea un ejecutable más pequeño con menos símbolos que generar. Ahorrar espacio, por tanto, tiene una doble ventaja, que es por lo que Vincular SDK es la opción predeterminada para todas las compilaciones de dispositivos.

Nota:

La opción Vincular SDK puede aparecer como Vincular solo SDK de marco o como Vincular solo ensamblados de SDK, en función del IDE utilizado.

Sugerencias

  • Compilación:
    • La compilación de una única arquitectura (por ejemplo, ARM64) es más rápida que un archivo binario FAT (por ejemplo, ARMv7 + ARM64).
    • Evite optimizar los archivos PNG al depurar.
    • Considere la posibilidad de vincular todos los ensamblados. Optimice cada ensamblado.
    • Deshabilite la creación de símbolos de depuración con --dsym=false. Sin embargo, debe tener en cuenta que, al deshabilitar esto, los informes de bloqueo solo pueden resolverse en el equipo que compiló la aplicación, y solo si la aplicación no se quitó.

Algunos aspectos que deben evitarse son:

  • Archivos binarios FAT (depurar)
  • Deshabilitar el enlazador --nolink
  • Deshabilitar eliminación
    • Símbolos --nosymbolstrip
    • IL (versión) --nostrip.

Sugerencias adicionales

  • Como en el simulador, es preferible la compilación a la recompilación.
    • Los ensamblados de AOT (archivos objeto) se almacenan en la memoria caché.
  • Las compilaciones de depuración tardan más por los símbolos, la ejecución de dsymutil y, debido a que al final son más grandes, se necesita tiempo adicional para cargarlas en los dispositivos.
  • De forma predeterminada, las compilaciones de versiones realizarán una eliminación de IL de los ensamblados. Esto lleva poco tiempo y es posible que se recupere al implementar una aplicación más pequeña en el dispositivo.
  • Evite implementar archivos estáticos grandes en cada compilación (depurar)
    • Utilice UIFileSharingEnabled (info.plist).
      • Los recursos se pueden cargar una vez.
  • En caso de duda, use la marca --time --time para medir el cambio.

En la captura de pantalla siguiente se ilustra cómo establecer estas opciones para el simulador en las opciones de iOS:

Screenshot shows Project Options, including Linker behavior, Supported architectures, and other settings.

Uso del enlazador

Al compilar la aplicación, mtouch usa un enlazador para el código administrado, que elimina el código que la aplicación no usa. En teoría, esto ofrece compilaciones más pequeñas, pero más rápidas. Para más información sobre el enlazador, vea la guía Vincular en iOS.

Considere esta opciones al usar el enlazador:

  • Al seleccionar No vincular para un dispositivo, la compilación tarda más tiempo y también genera una aplicación más grande.
    • Apple rechazará las aplicaciones si su tamaño supera el límite establecido. En función de MinimumOSVersion, el tamaño puede ser de solo 60 MB.
    • Se incluye el ejecutable nativo.
    • Usar No vincular es más rápido para las compilaciones del simulador, porque se usa la compilación JIT (en oposición a AOT en un dispositivo).
  • Vincular SDK es la opción predeterminada.
  • Puede que no sea seguro vincular todo, sobre todo si usa código que no es propio, como paquetes NuGet o componentes. Si decide no vincular los ensamblados, todo el código de estos servicios se incluye en la aplicación, con la posibilidad de crear aplicaciones más grandes.
    • No obstante, si elige Vincular todo, la aplicación puede bloquearse, sobre todo si se usan componentes externos. Esto se debe a que algunos componentes usan la reflexión en determinados tipos.
    • El análisis estático y la reflexión no funcionan de forma conjunta.

Se puede indicar a las herramientas que mantengan los elementos dentro de la aplicación con el atributo [Preserve].

Si no tiene acceso al código fuente o si lo genera una herramienta y no quiere cambiarlo, se puede vincular con la creación de un archivo XML en el que se describen todos los tipos y los miembros que deben conservarse. Puede agregar la marca --xml={file.name}.xml a las opciones del proyecto, que procesa código exactamente como si usara atributos.

Vinculación parcial de aplicaciones

También puede vincular aplicaciones de forma parcial, para ayudar a optimizar el tiempo de compilación de la aplicación:

  • Use Link All y omita algunos ensamblados.

    • Se pierde alguna optimización del tamaño de la aplicación.
    • No se requiere acceso al código fuente.
    • Por ejemplo: --linkall --linkskip=fieldserviceiOS.
  • Use la opción Link SDK y el atributo [LinkerSafe] en los ensamblados necesarios

    • Se requiere acceso al código fuente.
    • Indica al sistema que es seguro vincular el ensamblado y se procesa como si se tratara de un SDK de Xamarin.

Objective-C Bindings

  • Usar el atributo [Assembly: LinkerSafe] en los enlaces puede ahorrar tiempo y tamaño.

  • SmartLink

    • Se realiza en el lado nativo.
    • Se usa el atributo [LinkWith (SmartLink=true)].
    • Esto ayuda al enlazador nativo a eliminar el código nativo de la biblioteca con la que está realizando la vinculación.
    • Tenga en cuenta que la búsqueda dinámica de símbolos no funcionará con esto.

Resumen

En esta guía se analiza cómo controlar el tiempo de una aplicación iOS y las opciones que hay que considerar en función de las opciones y la configuración de compilación del proyecto.