Compilación anticipada de Xamarin.Mac

Información general

La compilación con antelación (AOT) es una técnica de optimización eficaz para mejorar el rendimiento de inicio. Sin embargo, también afecta al tiempo de compilación, al tamaño de la aplicación y a la ejecución del programa de forma profunda. Para comprender los inconvenientes que impone, vamos a profundizar un poco en la compilación y ejecución de una aplicación.

El código escrito en lenguajes administrados, como C# y F#, se compila en una representación intermedia denominada IL. Este IL, almacenado en la biblioteca y los ensamblados de programa, es relativamente compacto y portátil entre las arquitecturas de procesador. Il, sin embargo, es solo un conjunto intermedio de instrucciones y, en algún momento, el IL tendrá que traducirse en código de máquina específico del procesador.

Hay dos puntos en los que se puede realizar este procesamiento:

  • Just-In-Time (JIT): durante el inicio y la ejecución de la aplicación, el IL se compila en memoria en código de máquina.
  • Antes de tiempo (AOT): durante la compilación, el IL se compila y se escribe en bibliotecas nativas y se almacena dentro de la agrupación de aplicaciones.

Cada opción tiene una serie de ventajas y desventajas:

  • JIT
    • Tiempo de inicio : la compilación JIT debe realizarse durante el inicio. Para la mayoría de las aplicaciones, esto está en el orden de 100 ms, pero para las aplicaciones grandes esta vez puede ser significativamente más.
    • Ejecución : como el código JIT se puede optimizar para el procesador específico que se usa, se puede generar código ligeramente mejor. En la mayoría de las aplicaciones, esto es un porcentaje de puntos más rápido como máximo.
  • AOT
    • Tiempo de inicio : la carga de dylibs precompiladas es significativamente más rápida que los ensamblados JIT.
    • Espacio en disco : esas bibliotecas de datos pueden tomar una cantidad significativa de espacio en disco. En función de los ensamblados que sean AOTed, puede duplicar o más el tamaño de la parte de código de la aplicación.
    • Tiempo de compilación: la compilación AOT es significativamente más lenta que JIT y ralentizará las compilaciones que lo usan. Esta ralentización puede oscilar entre segundos y hasta un minuto o más, según el tamaño y el número de ensamblados compilados.
    • Ofuscación : como il, que es significativamente más fácil de invertir que el código de máquina, no es necesariamente necesario que se pueda quitar para ayudar a ofuscar el código confidencial. Esto requiere la opción "Híbrida" que se describe a continuación.

Habilitación de AOT

Las opciones de AOT se agregarán al panel Compilación de Mac en una actualización futura. Hasta entonces, habilitar AOT requiere pasar un argumento de línea de comandos a través del campo "Argumentos mmp adicionales" en Mac Build. Las opciones son las siguientes:

--aot[=VALUE]          Specify assemblies that should be AOT compiled
                          - none - No AOT (default)
                          - all - Every assembly in MonoBundle
                          - core - Xamarin.Mac, System, mscorlib
                          - sdk - Xamarin.Mac.dll and BCL assemblies
                          - |hybrid after option enables hybrid AOT which
                          allows IL stripping but is slower (only valid
                          for 'all')
                          - Individual files can be included for AOT via +
                          FileName.dll and excluded via -FileName.dll

                          Examples:
                            --aot:all,-MyAssembly.dll
                            --aot:core,+MyOtherAssembly.dll,-mscorlib.dll

AOT híbrido

Durante la ejecución de una aplicación macOS, el entorno de ejecución usa el código de máquina cargado desde las bibliotecas nativas generadas por la compilación AOT. Sin embargo, hay algunas áreas de código como trampolines, donde la compilación JIT puede producir resultados significativamente más optimizados. Esto requiere que el IL de los ensamblados administrados esté disponible. En iOS, las aplicaciones están restringidas a cualquier uso de la compilación JIT; esas secciones de código también se compilan AOT.

La opción híbrida indica al compilador que compile ambas secciones (como iOS), pero también para suponer que el IL no estará disponible en tiempo de ejecución. A continuación, este IL se puede quitar después de la compilación. Como se indicó anteriormente, el tiempo de ejecución se verá obligado a usar rutinas menos optimizadas en algunos lugares.

Otras consideraciones

Las consecuencias negativas de la escala AOT con los tamaños y el número de ensamblados procesados. El marco de destino completo, por ejemplo, contiene una biblioteca de clases base (BCL) significativamente mayor que la moderna y, por tanto, AOT tardará mucho más tiempo y generará agrupaciones más grandes. Esto se compone de la incompatibilidad del marco de destino completo con la vinculación, que elimina el código sin usar. Considere la posibilidad de mover la aplicación a Moderna y habilitar la vinculación para obtener los mejores resultados.

Una ventaja adicional de AOT incluye interacciones mejoradas con cadenas de herramientas de depuración y generación de perfiles nativas. Dado que una gran mayoría del código base se compilará con antelación, tendrá nombres de función y símbolos que son más fáciles de leer dentro de informes de bloqueo nativos, generación de perfiles y depuración. Las funciones generadas por JIT no tienen estos nombres y a menudo se muestran como desplazamientos hexadecimados sin nombre que son muy difíciles de resolver.